У меня есть класс 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, чтобы частично имитировать 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(...)
и тест пройден успешно, ПОЧЕМУ он не запускает блок?
Вопрос 2. Как правильно выполнить модульное тестирование такой функции, как -(void)doTask
, которая вызывает NSObject#performSelector:onThread:withObject:waitUntilDone:?
XCTestExpectation
иwaitForExpectationsWithTimeout:
, вот довольно хорошее объяснение этого bignerdranch.com/blog/asynchronous-testing-with-xcode-6 - person sbarow   schedule 15.06.2016