Модульное тестирование с NSURLConnection - PullRequest
3 голосов
/ 03 мая 2009

Я хочу протестировать фрагмент кода, который использует сеть (точнее, класс NSURLConnection). Код (назовем его NetworkManager) выглядит примерно так:

- (id) buildConnection
{
    // some more code and then:
    return [NSURLConnection …];
}

- (void) startNetworkSync
{
    id connection = [self buildConnection];
    //…
}

В модульном тесте я бы хотел избавиться от сети, т.е. замените объект NSURLConnection на макет. Как мне это сделать?

Я попытался создать частичный макет NetworkManager, который заменит метод buildConnection заглушкой. Проблема заключается в том, что частичные имитации, выполняемые OCMock только окурками из внешнего мира - отправка buildConnection из startNetworkSync вызывает оригинальный метод, а не заглушку.

Я также пытался «обезьянить» патч NetworkManager класса через категорию. Это работает, я могу легко переопределить метод buildConnection другим кодом и заменить реальный NSURLConnection заглушкой. Проблема в том, что я не нашел простого способа, которым я мог бы получить соединение с заглушкой в ​​тесте - соединение является частной частью NetworkManager.

Тогда я мог бы создать подкласс NetworkManager, переопределить метод buildConnection и добавить переменную экземпляра плюс метод доступа для созданного соединения. Это похоже на большой код.

Как бы вы решили это? Я ищу решение, которое поддерживает дизайн класса NetworkManager в чистоте и не требует большого количества магии или кода в тесте.

Ответы [ 3 ]

3 голосов
/ 03 мая 2009

Эта инъекция зависимостей предназначена для решения; если вместо этого вы используете startNetworkSyncWithConnection:(NSURLConnection*), вы можете легко протестировать метод с фиктивным соединением. Если вы не хотите изменять API для своих клиентов, вы можете даже оставить startNetworkSync в качестве оболочки, которая ничего не делает, кроме как вызвать этот новый метод с [self buildConnection] в качестве аргумента.

2 голосов
/ 15 мая 2009

Я изменил OCMock для поддержки реальных частичных имитаций, см. Репозиторий на GitHub .

0 голосов
/ 08 февраля 2012

Другое решение, которое я использовал недавно, - это полная абстракция сетевого интерфейса. Если классу нужны некоторые данные из сети, он, вероятно, взаимодействует с какой-либо серверной службой, которая может быть явно смоделирована как протокол:

@protocol SomeNetworkService
- (NSArray*) allAvailableFoos;
- (void) insertNewFoo: (Foo*) foo;
@end

И тогда у вас будет реальная реализация HTTP и тестовая реализация. Это означает больше работы, но также и лучшую тестируемость. Тесты менее хрупкие и гораздо более удобные, поскольку сетевой уровень тестирования может делать все, что вам нужно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...