2010-04-29 1 views
30

На мой рабочий день я был испорчен Mockito's never() verification, что может подтвердить, что метод макета никогда не вызывается.Как использовать OCMock для проверки того, что метод никогда не вызывается?

Есть ли способ сделать то же самое, используя Objective-C и OCMock? Я использовал код ниже, который работает, но это похоже на взлома. Я надеюсь, что есть лучший путь ...

- (void)testSomeMethodIsNeverCalled { 
    id mock = [OCMockObject mockForClass:[MyObject class]]; 
    [[[mock stub] andCall:@selector(fail) onObject:self] forbiddenMethod]; 

    // more test things here, which hopefully 
    // never call [mock forbiddenMethod]... 
} 

- (void)fail { 
    STFail(@"This method is forbidden!"); 
} 

ответ

59

Поскольку R 69 из OCMock, можно отклонить вызов метода http://svn.mulle-kybernetik.com/OCMock/trunk/Source/Changes.txt

Nice издевается/неспособность быстро Когда метод вызывается на макете объекта, не было установлено ни с ожиданием , либо с заглушкой макетного объекта будет вызывать исключение . Это отказоустойчивость быстрый режим может быть выключен путем создания «хорошо» издеваться:

id mock = [OCMockObject niceMockForClass:[SomeClass class]] 

Хотя хорошие издевается просто игнорировать все неожиданные методы можно запретить конкретные методы:

[[mock reject] someMethod] 

Обратите внимание, что в отказоустойчивом режиме, если исключение игнорируется, оно будет возвращено при вызове проверки. Это позволяет гарантировать, что могут быть обнаружены нежелательные вызовы от .

Цитируется: http://www.mulle-kybernetik.com/software/OCMock/#features

18

Насколько я знаю OCMock не сможет автоматически при вызове проверки и методы, которые не были записаны были названы. Макет, который не жаловался бы, если бы вызвали неожиданные методы, называется «приятным макетом».

- (void)testSomeMethodIsNeverCalled { 
    id mock = [OCMockObject mockForClass:[MyObject class]]; 

    [mock forbiddenMethod]; 
    [mock verify]; //should fail 
} 
+0

Это полностью сработало! Я не ожидал, что это будет так просто. Просто чтобы играть адвоката дьявола, как вы думаете, это скрывает намерение теста? –

+0

@ Justin: Ну, это требует от читателя узнать о поведении OCMock в этом случае, что не слишком очевидно. Достаточно добавить комментарий рядом с фиктивным контрольным вызовом, чтобы было ясно, что должно произойти. Например: '// проверка завершается неудачно, потому что мы вызвали неожиданный метод в mock.' –

0

Вы также можете попробовать что-то вроде этого, а-ля JavaScript:

- (void)aMethod { 
    __block BOOL b = NO; 

    id mock = [OCMockObject mockForClass:[UIView class]]; 
    [[[mock stub] andDo:^(NSInvocation *i) { b = YES; }] resignFirstResponder]; 
    [mock resignFirstResponder]; 

    NSLog(@"And b is: %i", b); // This reads "And b is: 1" on the console 
} 

Я не уверен, если есть какая-либо утечка, связанная с этим кодом. Я получил эту идею от чтения этой страницы: http://thirdcog.eu/pwcblocks/

3

Вы также можете найти его необходимо обеспечить метод никогда не вызывается на объект, который вы частично насмешливый.

Я создал макрос для этого:

#define andDoFail andDo:^(NSInvocation *invocation) { STFail(@"Should not have called this method!"); } 

Я использую это так:

[[[_myPartialMock stub] andDoFail] unexpectedMethod]; 
+0

Если вы используете современный OCMock, я рекомендую использовать' reject', как указано в других ответах. –

6

Начиная с версии 3.3 OCMock имеет OCMReject макросъемки.

id mock = OCMClassMock([MyObject class]); 
    OCMReject([mock forbiddenMethod]); 

    // exception will raise 
    [mock forbiddenMethod]; 
0

Чтобы убедиться, что ваш метод не называется, я думаю, что мы должны сделать Assert перед testMethod названием.Поэтому убедитесь, что ставить OCMReject перед запуском метода испытания, чтобы слушать, какой метод срабатывает, когда запускается testMethod:

OCMReject([mock someMethod]); 
[mock testMethod]; 
+2

Хотя этот фрагмент кода может решить проблему, он не объясняет, почему и как он отвечает на вопрос. Пожалуйста, [укажите объяснение своего кода] (// meta.stackexchange.com/q/114762/269535), так как это действительно помогает улучшить качество вашего сообщения. Помните, что вы отвечаете на вопрос читателей в будущем, и эти люди могут не знать причин вашего предложения кода. ** Флагеры/рецензенты: ** [Для ответов только на код, таких как этот, нисходящий, не удалять!] (// meta.stackoverflow.com/a/260413/2747593) – Patrick

+0

@Patrick Explanation добавлено –

Смежные вопросы