gpt4 book ai didi

ios - 如何创建在触发功能时通过的测试?

转载 作者:行者123 更新时间:2023-11-28 11:41:22 27 4
gpt4 key购买 nike

我正在尝试对 View Controller 类中的两个函数进行单元测试。这两个函数将分别创建用户和登录用户。我的测试与 UI 无关。

截至目前,我只需要创建一个在调用其中一个函数时通过的测试。目标是尽可能在不更改当前 View Controller 实现的情况下执行此操作,并将其全部保留在测试类/函数中。

我该怎么做?

谢谢

最佳答案

我假设一个 View Controller 具有调用“创建用户”或“登录用户”的方法。 (你说它与 UI 无关,但如果这是触发器,我们可以轻松测试按钮点击。)

class MyViewController: UIViewController {
func triggeringMethod() {
// Calls one of the two methods below
}

func createUser() {
// Does stuff
}

func signInUser() {
// Does stuff
}
}

而且听上去是想试流量,不想试效果。也就是说,您想测试“是否调用了 createUser()?”有多种方法可以获得您想要的内容,但更好的方法将要求您更改 View Controller 实现。

制作部分模拟

迈克尔·费瑟斯 (Michael Feathers) 的有效使用遗留代码 中的一个标准技巧是“子类化和重写方法”。让我们从那里开始。在测试代​​码中,我们可以使

class TestableMyViewController: MyViewController {
override func createUser() {
}

override func signInUser() {
}
}

到目前为止,这是一种消除这些方法影响的方法。但是我们现在可以从我的尝试中添加模拟技术! Swift 东京谈话。

class TestableMyViewController: MyViewController {
var createUserCallCount = 0
var signInUserCallCount = 0

override func createUser() {
createUserCallCount += 1
}

override func signInUser() {
signInUserCallCount += 1
}
}

现在您可以调用触发方法,并查看调用次数。

(您可能必须做出的更改:类不能是final。方法不能是private。)

移动 worker

虽然这是一个很好的起点,但不要止步于此。我们创建的是“部分模拟”。这是我们保留大部分功能的地方,但模拟了几个方法。这是要避免的事情。原因是我们最终得到了混合了生产代码和测试代码的类。如果您无意中测试了测试代码而不是测试生产代码,那么这种情况太容易结束了。

部分模拟清楚地表明我们缺少边界。 View Controller 做的太多了。 “创建用户”和“登录用户”的实际工作应该由另一种类型(甚至可能是两种类型)来执行。在 Swift 中,我们可以用一个协议(protocol)来定义这个边界。这样生产代码就可以使用真正的功能,而对于测试代码,我们可以注入(inject)模拟。

这意味着生产代码应该避免自己决定谁来做实际工作。相反,我们应该告诉谁在做这项工作。这样,测试可以提供替代 worker 。从外部指定这些依赖关系称为“依赖注入(inject)”。

回传效应

另一种选择可以让我们完全避免模拟。我们可以在枚举中描述所需的效果,而不是测试是否调用了某些东西。然后我们可以定义像这样的效果

enum Effect {
case createUser(CreateUserRequestModel)
case signInUser(SignInUserRequestModel)
}

触发方法不是调用 createUser()signInUser(),而是调用委托(delegate)。 (另一种选择是传递闭包而不是指定委托(delegate)。)

protocol Delegate {
perform(_ effect: Effect)
}

然后在触发方法中,

delegate?.perform(.createUser(parameters))

这意味着将这些枚举值转换为实际工作取决于实际委托(delegate)。但它使测试易于编写。我们所需要的只是提供一个测试实现来捕获 Effect 值。

关于ios - 如何创建在触发功能时通过的测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53568111/

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