我正在为UI的各个组件编写单元测试。但是,我在为触发异步函数的按钮编写测试时遇到了问题。我的问题是,我使用UIButton.sendActions(for controlEvents: UIControlEvents)
触发按钮的按下,然后调用异步函数。
假设我有个测试:
func testLoginToMainScene() {
loadView()
let queue = DispatchQueue(label: "LoginButtonPressed")
queue.sync {
view.loginButton.sendActions(for: .touchUpInside)
}
XCTAssertTrue(router.navigateToMainSceneCalled)
}
在
LoginViewController
类中测试以下代码位:@IBAction func loginButtonPressed(_ sender: AnyObject) {
hideKeyboard()
performLogin(email: emailTextField.text, password: passwordTextField.text)
}
以及通过调用redux工作者的方法来处理登录的函数:
private func performLogin(email: String, password: String) {
let result = myReduxWorker.getStore().dispatch(newLoginAction(email: email, password: password)
if let promise = result as? Promise<[String: Any]> {
promise.done { json -> Void in
//Login was successful!
router.navigateToMainScene()
}
}
当前,测试失败,因为
XCTAssertTrue
测试在performLogin
函数完成之前运行,因此在调用navigateToMainScene
之前运行。我试过使用DispatchQueue
,但是当.touchUpInside
操作发送到按钮时,.sync
中的代码块就完成了,测试函数继续并运行XCTAssertTrue
测试。在执行测试用例之前,确保
performLogin
函数已完成运行的最佳方法是什么? 最佳答案
在执行测试用例之前,确保performLogin
函数已完成运行的最佳方法是什么?
一般来说,最好的方法是让您的测试调用performLogin
函数。不要使用单元测试来触发或测试接口行为。只测试业务逻辑,并以使其可测试的方式分离出该业务逻辑。
然而,在您的情况下,可能您应该一直在这里编写的是一个UI测试,而不是一个单元测试。(我真的不能说,因为我不知道你在想什么,这种情况应该是可以测试的。)