我正在为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测试,而不是一个单元测试。(我真的不能说,因为我不知道你在想什么,这种情况应该是可以测试的。)

09-15 12:41
查看更多