unit testing - Swift Mocking Class -


as far know there no possible solution mocking , stubbing methods in swift used in objc ocmock, mockito, etc.

i'm aware of technique described here. quite useful in cases, had deadlock :)

i had service layer had contracts(calling method params return object callback). one(greatly simplified) example:

class bar {     func todata() -> nsdata     {         return nsdata()     } }  class foo {     class func fromdata(data: nsdata) -> foo     {         return foo()     } }  class servermanager {     let sharedinstance = servermanager()      class func send(request: nsdata, response: (nsdata)->())     {         //some networking code unrelated problem         response(nsdata())     } }  class mobileservice1 {     final class func contract1(request: bar, callback: (foo) -> ())     {         servermanager.send(request.todata()) { responsedata in             callback(foo.fromdata(responsedata))         }     }     //contract2(...), contract3(...), etc } 

therefore somewhere in code had following scenario:

func somewhereinthecode(somebool: bool, someobject: bar) {     if somebool     {         mobileservice1.contract1(someobject) { resultfoo in             //self.foo = resultfoo         }     }     else     {         //mobileservice1.contract2(...)     } } 

and question how heck test this? there better(for testing) alternative code structure without touching contracts themselves?

better late never found solution. make dependency injection of mobileservice1(or better of it's interface) , mock easily:

//declaring interface protocol mobileservicecontracts: class {     static func contract1(request: bar, callback: (foo) -> ()) }  //make implementation conform interface class mobileservice1 : mobileservicecontracts {     final class func contract1(request: bar, callback: (foo) -> ())     {         servermanager.send(request.todata()) { responsedata in             callback(foo.fromdata(responsedata))         }     }     //contract2(...), contract3(...), etc }  //inject service func somewhereinthecode(somebool: bool, someobject: bar, serviceprovider: mobileservicecontracts.type = mobileservice1.self) {     if somebool     {         serviceprovider.contract1(someobject) { resultfoo in             //self.foo = resultfoo         }     }     else     {         //mobileservice1.contract2(...)     } } 

now can change service in tests:

class mockedmobileservice1: mobileservicecontracts {     static func contract1(request: bar, callback: (foo) -> ()) {         //do whatever mock     } }  somewhereinthecode(false, someobject: bar(), serviceprovider: mockedmobileservice1.self) 

and best part default values can still call old way(not braking change):

somewhereinthecode(false, someobject: bar()) 

Comments

Popular posts from this blog

javascript - oscilloscope of speaker input stops rendering after a few seconds -

javascript - gulp-nodemon - nodejs restart after file change - Error: listen EADDRINUSE events.js:85 -

Fatal Python error: Py_Initialize: unable to load the file system codec. ImportError: No module named 'encodings' -