将模拟类注入unit testing方法
我试图unit testing一个依赖于另一个类的方法。 该方法调用该类的类方法,本质上是这样的:
func myMethod() { //do stuff TheirClass.someClassMethod() }
使用dependency injection技术,我想能够用模拟replace“TheirClass”,但我不知道如何做到这一点。 有没有办法通过模拟类 (而不是实例)?
编辑:感谢您的答复。 也许我应该提供更多的细节。 我试图模拟的类方法是在一个开源的库。
以下是我的方法。 我试图testing它,而嘲笑了对NXOAuth2Request.performMethod
的调用。 此类方法发出networking调用以从我们的后端获取经过身份validation的用户信息。 在closures时,我将这些信息保存到开源库提供的全局帐户存储中,并发布成功或失败的通知。
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) } }) } }
在Swift中,通过传递一个函数可以做得更好。 有很多方法可以解决这个问题,但是这里有一个:
func myMethod(completion: () -> Void = TheirClass.someClassMethod) { //do stuff completion() }
现在,您可以传递一个完成处理程序,而现有代码将继续使用默认方法。 注意如何引用函数本身( TheirClass.someClassMethod
)。 你不必把它包装在封口中。
你可能会发现让主叫方只是经常这样做,而不是将其设置为默认值。 这将使这个类更less绑定到TheirClass
类,但任何一种方式都是好的。
最好把这种松耦合,可testing性devise整合到代码本身中,而不是用巧妙的方式来模拟事物。 事实上,你应该问自己,如果myMethod()
应该真的调用someClassMethod()
。 也许这些东西应该分开,让它们更容易被testing,然后再把它们绑在一起。 例如,也许myMethod
应该返回一些你可以传递给someClassMethod()
,这样就没有你需要担心的状态。
- 错误使用Swift – 实例成员不能用于types'ViewController'
- 如何正确地closures作为模式呈现的UINavigationController?
- ios swift:如何在dynamictableview中有一个静态单元格?
- 如何使用childByAutoId更新Firebase中的值?
- Swift在debugging和发布模式下performance不同
- 如何在iOS应用程序中将.svg url显示为图像
- 什么时候使用快速closures?
- 尝试使用Grand Central Dispatch执行Realm事务时的RLMException
- 那么当服务器端添加新的项目时,如何加载表视图?