Swift NSCache Singleton
Yes, this isn't the canonical way. My solution is to not use Self and to instead focus on shared.
That is:
protocol ImageCacheProtocol {
    func getCache() -&gt; NSCache&lt;AnyObject, UIImage&gt;
}

final class ImageCache: ImageCacheProtocol {
    var cache: NSCache&lt;AnyObject, UIImage&gt; = NSCache&lt;AnyObject, UIImage&gt;()
    static var shared = ImageCache()
    
    private init() {}
    
    func getCache() -&gt; NSCache&lt;AnyObject, UIImage&gt; {
        return cache
    }
}

Then the mocks can be altered:
final class MockImageCache: ImageCacheProtocol {
    var cache: NSCache&lt;AnyObject, UIImage&gt; = MockNSCache(shouldReturnImage: true)
    public static var shared: ImageCacheProtocol! = MockImageCache()
    func getCache() -&gt; NSCache&lt;AnyObject, UIImage&gt; {
        return cache
    }
}