Вы создаете макет, но никогда не передаете его тестируемому классу или просите макет проверить себя.Вам нужна какая-то форма внедрения зависимости, чтобы сказать: «Вместо использования MFMailComposeViewController, используйте другую вещь, которую я вам даю».
Вот один из способов сделать это.В тестируемом классе вместо непосредственного размещения MFMailComposeViewController получите его с помощью фабричного метода, например:
@interface TestClass : NSObject
- (void)testMethod;
// Factory methods
+ (id)mailComposeViewController;
@end
Вот реализация.Вы просочились, поэтому обратите внимание, что метод фабрики возвращает автоматически освобожденный объект.
- (void)testMethod {
MFMailComposeViewController *mailComposeVC =
[[self class] mailComposeViewController];
[mailComposeVC setSubject:@"Bad Message"];
}
+ (id)mailComposeViewController {
return [[[MFMailComposeViewController alloc] init] autorelease];
}
На стороне тестирования мы создаем подкласс тестирования, который переопределяет метод фабрики, поэтому он предоставляет все, что мы хотим:
@interface TestingTestClass : TestClass
@property(nonatomic, assign) id mockMailComposeViewController;
@end
@implementation TestingTestClass
@synthesize mockMailComposeViewController;
+ (id)mailComposeViewController {
return mockMailComposeViewController;
}
@end
Теперь мы готовы к тесту.Я делаю несколько вещей по-другому:
- Выделите подкласс тестирования, а не фактический класс (и не пропустите!)
- Настройте макет с ожиданием, а не простозаглушка
- Вставить макет в подкласс тестирования
- Проверить макет в конце
Вот тест:
- (void) testEmail {
TestClass *testInstance = [[[TestClass alloc] init] autorelease];
id mock = [OCMockObject mockForClass:[MFMailComposeViewController class]];
[[mock expect] setSubject:@"Test Message"];
[testInstance setMockMailComposeViewController:mock];
[testInstance testMethod];
[mock verify];
}
Для полнотынам нужен один последний тест, и это гарантирует, что фабричный метод в реальном классе возвращает то, что мы ожидаем:
- (void)testMailComposerViewControllerShouldBeCorrectType {
STAssertTrue([[TestClass mailComposeViewController]
isKindOfClass:[MFMailComposeViewController class]], nil);
}