gpt4 book ai didi

ios - 将模拟类注入(inject)到单元测试方法的方法中

转载 作者:搜寻专家 更新时间:2023-10-31 08:23:49 25 4
gpt4 key购买 nike

我正在尝试对依赖于另一个类的方法进行单元测试。该方法调用该类的类方法,本质上是这样的:

func myMethod() {

//do stuff
TheirClass.someClassMethod()

}

使用依赖注入(inject)技术,我希望能够用模拟替换“TheirClass”,但我不知道该怎么做。有什么方法可以传入模拟(不是实例)吗?

编辑:感谢您的回复。也许我应该提供更多细节。我试图模拟的类方法在一个开源库中。

下面是我的方法。我正在尝试测试它,同时模拟对 NXOAuth2Request.performMethod 的调用。此类方法发出网络调用以从我们的后端获取经过身份验证的用户的信息。在闭包中,我将此信息保存到开源库提供的全局帐户存储中,并发布成功或失败的通知。

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)。您不必将其包裹在闭包中。

您可能会发现让调用者始终传递它比将其设为默认值更好。这将使此类与 TheirClass 的绑定(bind)减少,但无论哪种方式都可以。

最好将这种松耦合、可测试性设计集成到代码本身,而不是想出巧妙的方法来模拟事物。事实上,您应该问问自己 myMethod() 是否真的应该调用 someClassMethod()。也许应该将这些东西拆分开来让它们更容易测试,然后在更高的层次上将它们联系在一起。例如,也许 myMethod 应该返回一些您可以随后传递给 someClassMethod() 的内容,这样您就无需担心任何状态。

关于ios - 将模拟类注入(inject)到单元测试方法的方法中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28115991/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com