Swift testing with protocols

In this post, we shall see how protocols work with unit testing.

Say, you have a downloader class DownloadFileClass for fetching network data. It follows the protocol DownloadFileProtocol. The whole class and protocol looks like this.


protocol DownloadFileProtocol {
    func downloadFile(with name: String, completion: (String) -> ())
}

class DownloadFileClass {
    
    var downloadedFile: String = ""
    
    init(downloadProtocol: DownloadFileProtocol) {
        downloadProtocol.downloadFile(with: "something", completion: {value in
            print("Value \(value)")
            self.downloadedFile = value
        })
    }
}

Say you have to test this class. Obviously you cannot download an actual file. But you can actually mock this call with the protocol during unit testing.

In your unit test, make the DummyFileDownloader which actually implements this protocol and adds dummy implementation. You can read local json file in it instead of making actual network request since it is just a test.


class DownloadFileSpec: QuickSpec {
    class DummyFileDownloader: DownloadFileProtocol {
        func downloadFile(with name: String, completion: (String) -> ()) {
            print("Downloading dummy file")
            completion("dummy data")
            
        }
    }
}

Now in your downloader class you can actually pass this dummy downloader which adheres to DownloadFileProtocol and test its behavior.


override func spec() {
        describe("Sample testing") {
            it("This test should correctly mock the desired function call", closure: {
                let downloader = DownloadFileClass(downloadProtocol: DummyFileDownloader())
                expect(downloader.downloadedFile).to(equal("dummy data"))
            })
        }
}

This should be it. By mocking with dummy class which adheres to protocol, you can inject any value you want as a response to network call and verify it with expecta conditions.

This is just a beginning. I am sure you can do lot of fancy things with protocol oriented approach that Swift offers. If you can think of anything else, please let me know. In the next part, I will show how to write Swift unit tests to test singletons