ios - 测试是否在 View Controller 方法中调用了 performSegueWithIdentifier

标签 ios objective-c unit-testing ocmock xctest

我正在检查一个应用程序并添加单元测试。该应用程序使用 Storyboard编写,支持 iOS 6.1 及更高版本。

我已经能够毫无问题地测试所有常用的返回方法。但是,我目前对要执行的某个测试感到困惑:

本质上我有一个方法,我们称之为 doLogin:

- (IBAction)doLogin:(UIButton *)sender {

// Some logic here

if ( //certain criteria to meet) {
    variable = x; // important variable set here
    [self performSegueWithIdentifier:@"memorableWord" sender:sender];
} else {
    // handler error here
}

所以我想测试是否调用了 segue 并设置了变量,或者是否加载了 MemorableWord View Controller 并且其中的变量是否正确。在 doLogin 方法中设置的变量被传递到 prepareForSegue 方法中的 memorableWord segues 目标 View Controller 。

我设置并运行了 OCMock,我还使用 XCTest 作为我的单元测试框架。有没有人能够制作单元测试来涵盖这种情况??

Google 和 SO 似乎在这方面的信息方面非常空白。许多简单的基本测试示例与 iOS 测试的更复杂的现实无关。

最佳答案

你走在正确的轨道上,你的测试想要检查:

  1. 当登录按钮被点击时,doLogin 被调用,loginButton 作为发送者
  2. 如果某些条件为 YES,则调用 performSegue

所以你实际上应该触发从登录按钮到 performSegue 的完整流程:

- (void)testLogin {
    LoginViewController *loginViewController = ...;
    id loginMock = [OCMockObject partialMockForObject:loginViewController];

    //here the expect call has the advantage of swallowing performSegueWithIdentifier, you can use forwardToRealObject to get it to go all the way through if necessary
    [[loginMock expect] performSegueWithIdentifier:@"memorableWord" sender:loginViewController.loginButton];

    //you also expect this action to be called
    [[loginMock expect] doLogin:loginViewController.loginButton];

    //mocking out the criteria to get through the if statement can happen on the partial mock as well
    BOOL doSegue = YES;
    [[[loginMock expect] andReturnValue:OCMOCK_VALUE(doSegue)] criteria];

    [loginViewController.loginButton sendActionsForControlEvents:UIControlEventTouchUpInside];

    [loginMock verify]; [loginMock stopMocking];
}

您需要为“criteria”实现一个属性,以便有一个可以使用“expect”模拟的 getter。

重要的是要认识到“expect”只会模拟 1 次对 getter 的调用,后续调用将失败并显示“调用了意外的方法...”。您可以使用“ stub ”模拟所有调用,但这意味着它将始终返回相同的值。

关于ios - 测试是否在 View Controller 方法中调用了 performSegueWithIdentifier,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20609283/

相关文章:

android - Robolectric:测试取消对话不会启动新 Activity

android - 连续的 Android Junit 测试不反射(reflect)底层数据库中的真实数据

ios - Swift - 如何在tableView顶部插入单元格保持偏移和滚动惯性

ios - 使用 Xamarin 的通用约束

objective-c - 格式化 NSString 中的日期

objective-c - 在 Xcode 中使用 Yacc 和 Lex

iphone - Facebook iOS SDK : Login to Facebook without always ask for permissions for the application

ios - 在 iOS7 Swift 项目中包含来自 Swift 源的 Pod

objective-c - Google SDK 的 Apple Mach-O 链接器错误

ios - RxSwift 在模拟的 UserDefaults 上观察测试用例