Я использую XCTest
и OCMock
для написания модульных тестов для приложения iOS, и мне нужно руководство о том, как наилучшим образом разработать unit test, который проверяет, что метод приводит к запуску NSTimer
.
Проверяемый код:
- (void)start {
...
self.timer = [NSTimer timerWithTimeInterval:1.0
target:self
selector:@selector(tick:)
userInfo:nil
repeats:YES];
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop addTimer:self.timer forMode:NSDefaultRunLoopMode];
...
}
Что я хочу проверить, так это то, что таймер создан с правильными аргументами и что таймер планируется запустить в цикле выполнения.
Я подумал о следующих вариантах, которые мне не нравятся:
- На самом деле дождитесь срабатывания таймера. (Причина мне не нравится: ужасная практика тестирования модулей. Это больше похоже на медленный тест интеграции.)
- Извлеките стартовый код таймера в частный метод, покажите этот закрытый метод в файле расширения класса для тестирования модуля и используйте макетное ожидание, чтобы проверить, вызван ли частный метод. (Причина мне не нравится: он проверяет, вызван ли метод, но не тот метод, который фактически устанавливает правильную работу таймера. Также, разоблачение частных методов не является хорошей практикой.)
- Предоставить макет
NSTimer
тестируемому коду. (Причина мне не нравится: не удается проверить, что на самом деле она запускается по расписанию, потому что таймеры запускаются через цикл запуска, а не из некоторого метода запускаNSTimer
.) - Предоставьте макет
NSRunLoop
и убедитесь, чтоaddTimer:forMode
: вызывается. (Причина мне не нравится: я должен был бы предоставить интерфейс в цикл цикла? Это кажется дурацким.)
Может ли кто-нибудь предоставить некоторый кодекс для тестирования модулей?