使用 OCMock 对本地对象或依赖注入进行单元测试?

unit test local objects or dependency injection with OCMock?

正在尝试为以下功能创建简单测试:

-(void)presentWithString:(NSString *)name
{
    CustomVC *customVC = [[CustomVC alloc] initWithName:name];
    UINavigationController *nav = [[UINavigationController alloc] init];
    nav.viewControllers = @[customVC];

    dispatch_async(dispatch_get_main_queue(), ^{
        [self.vc presentViewController:nav animated:YES completion:nil];
    });
}

我可以通过依赖注入将其拆分成块,但不知道如何以任何一种方式编写正确的测试。此示例的最佳做法是什么?

想要测试什么?您的方法中发生了 3 件事:

  1. CustomVC 已通过 name 创建。
  2. CustomVC 嵌入在导航控制器中。
  3. 导航控制器显示在 self.vc

您可以编写一个测试来检查整个流程:

- (void)testPresentWithString_shouldPresentCustomVC_withPassedName {

    // Arrange
    NSString *expectedName = @”name”;
    XCTestExpectation *exp = [self expectationWothDescription:@”presentVC called”];

    TestClass *sut = [[TestClass alloc] init];
    id vcMock = OCMClassMock([UIViewController class]);
    sut.vc = vcMock;

    OCMExpect([vcMock presentViewController:OCM_ANY animated:YES completion:nil]).andDo(^(NSInvocation *invocation) {

        UINavigationController *nav = nil;
        [invocation getArgument:&nav atIndex:2];

        CustomVC *custom = nav.viewControllers.firstObject;

        // Assert
        XCTAssertNotNil(nav);
        XCTAssertTrue([nav isKindOfClass:[UINavigationController class]]);
        XCTAssertEqual(nav.viewControllers.count, 1);
        XCTAssertNotNil(custom);
        XCTAssertTrue([custom isKindOfClass:[CustomVC class]]);
        XCTAssertEqual(custom.name, expectedName);

        [exp fulfill];
    });

    // Act
    [sut presentWithString:expectedName];

    // Assert
    [self waitForExpectationsWithTimeout:1 handler:nil];
    OCMVerifyAll(vcMock);

    // Cleanup
    [vcMock stopMocking];
}

此代码检查您的方法中发生的所有事情 - 一个方法被调用时带有特定参数,这些参数中的第一个是仅嵌入 CustomVC 的导航控制器,并且此 CustomVC设置了 name。显然,我假设可以从外部设置测试 class 上的 vc 属性,并且可以读取 CustomVC 上的 name。如果没有,测试其中的某些部分可能会更棘手。

就我个人而言,我不会对此进行单元测试。我将单独测试 CustomVC 的初始化,并将整个演示文稿置于 UI 测试之下。

如果一切都清楚,请告诉我!

旁注:我是凭记忆在手机上写的,所以代码中可能会有小错误。当我有机会用Xcode检查它时,我会更新它。