iOS开发新手:如何编写测试验证视图控制器带动画Dismiss
嘿,我来帮你搞定这个AboutViewController的单元测试问题!😎
要测试homeButtonTouched(_:)方法是否正确调用了带动画的dismiss,我们可以通过创建一个Mock视图控制器来跟踪dismiss方法的调用情况——毕竟直接测试控制器是否消失在单元测试里不太直观,而验证方法调用和参数才是单元测试的核心。
完整的测试实现步骤:
- 首先在你的测试类里定义一个MockViewController,用来记录
dismiss的调用状态和参数:
class MockViewController: UIViewController { // 记录dismiss是否被调用 var didTriggerDismiss = false // 记录dismiss时传入的animated参数值 var dismissAnimatedFlag: Bool? override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) { // 更新记录状态 didTriggerDismiss = true dismissAnimatedFlag = flag // 调用父类方法保证正常流程 super.dismiss(animated: flag, completion: completion) } }
- 然后填充
testHomeButtonTouched()方法的内容:
func testHomeButtonTouched() { // 1. 创建Mock控制器作为AboutVC的presenting控制器 let mockPresenter = MockViewController() // 2. 用Mock控制器present我们的AboutVC(这里不需要动画,不影响测试) mockPresenter.present(aboutViewController, animated: false) // 3. 直接触发按钮点击方法(模拟用户点击) aboutViewController.homeButtonTouched(UIButton()) // 4. 验证核心逻辑:dismiss被调用,且animated参数为true XCTAssertTrue(mockPresenter.didTriggerDismiss, "点击Home按钮应该触发dismiss方法") XCTAssertEqual(mockPresenter.dismissAnimatedFlag, true, "dismiss应该带动画执行") }
为什么这么做?
- 我们的目标是测试
homeButtonTouched(_:)的业务逻辑:点击按钮 → 调用dismiss(animated: true),而不是测试UIKit的dismiss功能本身(那是苹果的工作😉)。 - 通过Mock控制器,我们可以精准跟踪方法调用的细节,确保参数符合预期,这比直接观察UI消失要可靠得多。
如果想要更严谨地等待动画完成(虽然单元测试里通常不需要),可以加上XCTestExpectation来异步等待:
func testHomeButtonTouchedWithAnimationWait() { let mockPresenter = MockViewController() mockPresenter.present(aboutViewController, animated: false) let dismissExpectation = self.expectation(description: "等待dismiss动画完成") // 延迟等待动画队列完成 DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { dismissExpectation.fulfill() } aboutViewController.homeButtonTouched(UIButton()) waitForExpectations(timeout: 1, handler: nil) XCTAssertTrue(mockPresenter.didTriggerDismiss) XCTAssertEqual(mockPresenter.dismissAnimatedFlag, true) }
不过对于单元测试来说,第一种方法已经完全足够覆盖需求啦!
内容的提问来源于stack exchange,提问作者Erika
相关产品推荐
相关产品推荐

