尝试为以下功能创建简单测试:
-(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];
});
}
我可以将其拆分为具有依赖注入的块,但不知道如何以任何方式编写适当的测试。这个例子的最佳做法是什么?
答案 0 :(得分:1)
你想要测试什么?您的方法中发生了三件事:
CustomVC
是在name
通过后创建的。CustomVC
嵌入在导航控制器中。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
{ {1套。显然,我假设可以从外部设置测试类的vc
属性,并且可以读取name
上的CustomVC
。如果没有,测试其中的某些部分可能会比较棘手。
我个人不会对此进行单元测试。我将分别测试CustomVC
的初始化,并将整个演示文稿放在UI测试中。
如果一切都清楚,请告诉我!
-
旁注:我是通过内存在移动设备上写的,所以代码中可能会出现小错误。当我有机会用Xcode检查时,我会更新它。