Функциональные тесты с KIF: beforeEach вызывается после загрузки моего контроллера представления?
У меня есть простой (я предполагаю) вопрос.
Я хочу сделать функциональный тест в своем приложении с помощью Specta и KIF. Проблема в том, что я устанавливаю зависимость в методе viewDidLoad моего View Controller, а в методе beforeEach моей спецификации я внедряю поддельный объект, чтобы не попасть в сеть.
Результат неверный, потому что viewDidLoad вызывается методом beforeEach в спецификации.
Есть ли возможность установить зависимости до того, как AppDelegate загрузит контроллер корневого представления, чтобы все было настроено правильно?
1 ответ
Тесты, которые зависят от цели (например, KIF и некоторые модульные тесты), запускаются после запуска приложения, поэтому нет, вы не можете заставить beforeEach работать до вашего AppDelegate без какой-либо ужасной атаки.
Я не знаю, как вы делаете внедрение зависимости, вот как мы это делаем / некоторые общие стратегии.
Тесты KIF в идеале не должны издеваться над уровнем кода
Это потому, что KIF является своего рода альтернативой UIAutomation и в основном полезен для функциональных / функциональных тестов на уровне UI. Вы действительно не хотите так сильно менять код своего приложения. Мокость лучше всего достигается с помощью фреймворков, таких как OHHTTPStubs для сети или OCMock для объектов, и они работают лучше всего, когда ограничены модульными тестами.
Как макетировать сетевые запросы в "реальном" приложении
Лучший способ здесь - использовать что-то вроде OHHTTPStubs или сервера AMY (созданного теми же людьми, которые создали KIF) или Nocilla для возврата ответов на заглушки. Таким образом, вы можете позволить своему коду приложения работать полностью. Например, OHHTTPStubs использует NSURLProtocol для перехвата ваших запросов, поэтому с точки зрения приложения это почти так же хорошо, как выход в сеть.
Я действительно хочу издеваться над этими объектами
Если вы действительно хотите смоделировать объекты, добавленные в зависимости, с различными объектами, тогда есть пара более и менее хакерских опций.
1) Используйте реальную структуру DI (или создайте свою собственную), которая позволяет вносить исправления в зависимости. Я использовал Тайфун, и это разумно. Стандартная идея здесь - использовать Inversion of Control в ваших интересах. Поскольку вы получаете все свои объекты из контекста приложения, а не напрямую, гораздо проще настроить уровень абстракции контекста приложения. У "Тайфуна" даже есть вики-страница на эту тему: https://github.com/appsquickly/Typhoon/wiki/Integration-Testing
2) Проследите источник объекта, который вы вводите и хотите смоделировать и изменить его в источнике. Это не самый элегантный вариант, и вы все равно взламываете DI-фреймворк, но, возможно, у вас недостаточно времени или сложности, чтобы переключиться на DI-фреймворк.
3) Взломать весь путь до верхнего уровня. Создайте тест AppDelegate для подклассов вашего обычного AppDelegate и используйте его во время тестирования KIF (и, конечно, отключите его или макетируйте нужные вам объекты). Это не гибко, но опять же, может быть, вы просто хотите один тестовый пример или что-то:
int main(int argc, char *argv[])
{
int returnValue;
@autoreleasepool {
BOOL inIntegrationTests = NSClassFromString(@"KIFTestCase") != nil;
if (inIntegrationTests) {
returnValue = UIApplicationMain(argc, argv, nil, @"AppDelegateForTest");
}
else {
returnValue = UIApplicationMain(argc, argv, nil, @"AppDelegate");
}
}
return returnValue;
}
В конце концов, это, к сожалению, непростой вопрос "куда мне поместить этот метод"?