OCMock и AFHTTPRequestOperationManager

Я пытаюсь создать макет для AFHTTPRequestOperationManager AFNetworking, используя OCMock.

Вот что у меня есть:

id mockRequestManager = OCMClassMock([AFHTTPRequestOperationManager class]);
OCMStub([mockRequestManager manager]).andReturn(mockRequestManager);
[myObject methodThatUsesAFHTTPRequestOperationManager];

Я делал то же самое раньше для других синглетонов (например, [NSNotificationCenter defaultCenter]), но с AFHTTPRequestOperationManager я не возвращаю издевательский объект, когда [AFHTTPRequestOperationManager manager] вызывается из [myObject methodThatUsesAFHTTPRequestOperationManager]. Я всегда возвращаю объект экземпляра AFHTTPRequestOperationManager.

Я что-то пропустил? Есть ли какие-то детали реализации AFHTTPRequestOperationManager, которые мешают этому работать?

ИЗМЕНИТЬ

Итак, после просмотра кода AFHTTPRequestOperationManager оказывается, что на самом деле это не синглтон, а просто метод класса, который возвращает новый объект AFHTTPRequestOperationManager. Однако я до сих пор не понимаю, почему заглушка метода класса не возвращает мой фиктивный объект вместо создания нового.


person Jordan    schedule 25.08.2014    source источник


Ответы (1)


Как вы говорите, это не синглтон. Вместо этого вы можете ввести его; взгляните на этот ответ.

Использование инъекций предпочтительнее, чем синглтоны. В случае, если вы не хотите вводить типичные объекты, такие как [NSNotificationCenter defaultCenter] из [NSUserDefaults standardUserDefaults], вместо того, чтобы имитировать и заглушать метод доступа к общему экземпляру, вы можете просто использовать реальный объект в своих тестах. Например, вместо проверки того, что вы публикуете конкретное уведомление, имитирующее defaulCenter, вы можете прослушать это уведомление в своем тесте. Мне это решение нравится больше, поскольку оно позволяет избежать использования моков, и мы можем сказать, что оно более надежно, поскольку вы тестируете свой объект в сочетании с реальным центром уведомлений. Некоторые люди могут сказать, что тогда тест будет интеграционным тестом, но ИМО не стоит делать никаких различий в этом случае.

Что касается заглушки метода доступа к общему экземпляру, я не привык к новому синтаксису OCMock, но с этим не должно быть проблем, посмотрите, как заглушить метод класса с помощью OCMock.

person e1985    schedule 29.08.2014
comment
Я видел этот другой пост, пытаясь исследовать этот вопрос. У меня нет проблем с заглушкой других методов класса, в частности, этого. Я мог бы внедрить объект AFHTTPRequestOperationManager, но это возложило бы ответственность за создание объекта на другой класс в проекте только ради возможности протестировать этот класс. Причина, по которой я хочу поиздеваться над этим, в первую очередь заключается в перехвате GET:parameters:success:failure: поэтому мой тест не полагается на реальный сетевой вызов. Я не знаю способа наблюдать за этим, как вы можете с сообщениями уведомлений. - person Jordan; 29.08.2014
comment
IMO иметь класс, отвечающий за создание и управление жизненным циклом или вашими объектами, — это хорошо, поскольку это помогает вам отделить связующий код от бизнес-логики. Кроме того, проверьте Nocilla (github.com/luisobo/Nocilla), библиотеку для заглушки сети. звонит с легкостью. С его помощью вы можете протестировать свой код без необходимости имитировать AFHTTPRequestOperationManager. - person e1985; 30.08.2014