我有一个MyService
类继承NSThread
:
头:
@interface MyService : NSThread {
-(void) startMe;
-(void) doTask;
...
}
实现:
@implementation MyService
-(void)startMe {
[self start];
}
-(void) doTask {
[self performSelector:@selector(checkData:) onThread:self withObject:nil waitUntilDone:YES];
}
-(void) checkData {
...
// NOTE: dataChecked is an instance variable.
dataChecked = YES;
}
@end
我想对上面的-(void)doTask
进行单元测试,并验证是否真的调用了-(void)checkData
。我使用OCMock library来部分模仿MyService
&尝试了以下方式:
-(void) testCheckData {
// partial mock MyService
id myService = [OCMockObject partialMockForObject:[MyService getInstance]];
[myService startMe];
// function to test
[myService doTask];
// I wait 2 seconds for checkData to finish its work
dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC));
dispatch_after(delayTime, dispatch_get_main_queue(), ^(void){
// When running this test case, these code is never called & test passed successfully, WHY?
NSLog(@"Check if checkData does its work");
XCTAssertTrue([self isDataChecked]);
});
}
两个问题:
Q1。如上所述,在我的测试案例中,我致电-(void)doTask
& 等待2秒,期望执行-(void)checkData
,然后断言结果,但在运行测试用例时,它不会在dispatch_after(...)
&运行测试用例。测试成功通过,为什么它没有运行块?
Q2。对-(void)doTask
这样调用NSObject#performSelector:onThread:withObject:waitUntilDone:的函数进行单元测试的正确方法是什么?
答案 0 :(得分:0)
<强> Q1 强>
如果您无法更改doTask
以使其可测试,则必须使用XCTestExpectation
等待测试完成。此外,您应该忙于循环,在每次迭代时检查变量,而不是等待预设的时间。您可以在预期之后设置超时,以便在一段合理的时间后触发故障。
// setup expectation
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
while (dataChecked == NO);
// signal expectation
});
// wait for expectation
<强> Q2 强>
如果你必须知道成功测试它的方法的实现,它不适合单元测试。测试方法如何调用其他方法并不重要。只有当副作用同步或异步完成时才重要。