Цель C - Тестирование и издевательство объектов?
Как вы unit test Objective C code? (IPhone)
В других языках, таких как java и .Net, вы можете использовать Dependency Injection, чтобы иметь возможность unit test и передавать изделенный объект в свой текущий код.
Тем не менее, я не смог найти надежную среду инъекций зависимостей для объективных c.
Скажем, вы хотите написать unit test для приведенного ниже кода, как вы можете издеваться над MyObject?
- (void) methodToBeTested
{
NSString str = @"myString";
MyObject object = [[MyObject alloc] init];
[object setString:str];
[object doStuff];
[object release];
}
Вот как я буду делать это с помощью инъекции зависимостей. Есть ли аналогичный способ достижения этого на объективном c?
@Inject MyObject object;
public void methodToBeTested()
{
String str = "myString";
// object is automatically instantiated (Dependency Injection)
object.setString(str);
object.doStuff();
}
Ответы
Ответ 1
Инверсия управления по-прежнему возможна в objective-c. Конечно, вы можете разработать свои классы с учетом зависимости от конструктора или на основе свойств, но я не думаю, что вы найдете инфраструктуру инъекций зависимостей на основе аннотаций, как вы привыкли.
[[ClassToBeTested alloc] initWithDependency:foo andOtherDepedency:bar];
ClassToBeTested *objectUnderTest = [[ClassToBeTested alloc] init];
objectUnderTest.dependency = foo;
objectUnderTest.otherDependency = bar;
Я видел несколько разных подходов к созданию инфраструктур инъекций зависимостей для objective-c, включая https://github.com/mivasi/Objective-IOC, но я не могу прокомментировать их зрелость или полезность.
Для объекта, который насмехается и стучит, смотрите OCMock.
Ответ 2
как вы можете издеваться над MyObject?
- (void) methodToBeTestedWithObject:(MyObject *)object
{
NSString str = @"myString";
[object setString:str];
[object doStuff];
}
Чтобы проверить:
- (void)testMethodToBeTested {
id mockMyObject = [OCMock mockForClass:[MyObject class]];
[[mockMyObject expect] setString:[OCMock any]];
[[mockMyObject expect] doStuff];
[objectToTest methodToBeTestedWithObject:mockMyObject];
[mockMyObject verify];
}
Используя, как упоминалось в ответе @Jonah, отличный OCMock. Не утруждайте себя попыткой сделать капитализацию D, капиталоемкую инъекцию Injection в obj-c, она больше работает, чем стоит.
Ответ 3
Здесь вставка для зависимостей для Objective-C: http://www.typhoonframework.org
Помимо адресации по аспектам дизайна DI, он уделяет особое внимание возможности конфигурирования компонентов для производственных и тестовых сценариев (интеграционное тестирование). Это включает в себя:
- Возможность ввода значений, представляемых в виде строк, - они преобразуются в требуемый тип во время выполнения.
- Управление конфигурацией через внешний файл свойств.
- Выполнение асинхронных тестов - позволяет вам тестировать методы, выполняемые в фоновом потоке.