Inject mock method into unit test method

I am trying to use the unit test method, which has a dependency on another class. The method calls the class method for this class, basically this:

func myMethod() { //do stuff TheirClass.someClassMethod() } 

Using the dependency injection method, I would like to be able to replace β€œTheirClass” with the layout, but I cannot figure out how to do this. Is there a way to go in the mock class (and not in the instance)?

EDIT: Thanks for the answers. Perhaps I should have presented in more detail. The class method I'm trying to make fun of is in an open source library.

Below is my method. I am trying to test it by mocking the call to NXOAuth2Request.performMethod . This class method issues a network call to retrieve authenticated user information from our backend. In closing, I store this information in the global account repository provided by the open source library and post notifications of successes or failures.

 func getUserProfileAndVerifyUserIsAuthenticated() { //this notification is fired when the refresh token has expired, and as a result, a new access token cannot be obtained NSNotificationCenter.defaultCenter().addObserver(self, selector: "didFailToGetAccessTokenNotification", name: NXOAuth2AccountDidFailToGetAccessTokenNotification, object: nil) let accounts = self.accountStore.accountsWithAccountType(UserAuthenticationScheme.sharedInstance.accountType) as Array<NXOAuth2Account> if accounts.count > 0 { let account = accounts[0] let userInfoURL = UserAuthenticationScheme.sharedInstance.userInfoURL println("getUserProfileAndVerifyUserIsAuthenticated: calling to see if user token is still valid") NXOAuth2Request.performMethod("GET", onResource: userInfoURL, usingParameters: nil, withAccount: account, sendProgressHandler: nil, responseHandler: { (response, responseData, error) -> Void in if error != nil { println("User Info Error: %@", error.localizedDescription); NSNotificationCenter.defaultCenter().postNotificationName("UserCouldNotBeAuthenticated", object: self) } else if let data = responseData { var errorPointer: NSError? let userInfo = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &errorPointer) as NSDictionary println("Retrieved user info") account.userData = userInfo NSNotificationCenter.defaultCenter().postNotificationName("UserAuthenticated", object: self) } else { println("Unknown error retrieving user info") NSNotificationCenter.defaultCenter().postNotificationName("UserCouldNotBeAuthenticated", object: self) } }) } } 
+4
ios swift
source share
1 answer

In Swift, this is best done by passing a function. There are many ways to approach this, but here is one of them:

 func myMethod(completion: () -> Void = TheirClass.someClassMethod) { //do stuff completion() } 

Now you can pass the completion handler while existing code will continue to use the default method. Note how you can access the function itself ( TheirClass.someClassMethod ). You do not need to close it by closing.

You might be better off if the caller just walks all this time and not makes it the default. That would make this class less tied to TheirClass , but that is normal anyway.

It’s best to integrate this kind of loose connection, a design for testing in the code itself, and not come up with smart ways to mock things. In fact, you should ask yourself if myMethod() really called someClassMethod() at all. Perhaps these things should be separated to make them more easily verified, and then link them together at a higher level. For example, perhaps myMethod should return what you can then pass to someClassMethod() so that there is no state that you need to worry about.

+6
source share

All Articles