Как я могу использовать OCMock, чтобы убедиться, что метод никогда не вызывается? - PullRequest
33 голосов
/ 29 апреля 2010

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

Есть ли способ сделать то же самое, используя 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!");
}

Ответы [ 6 ]

61 голосов
/ 19 апреля 2011

Начиная с r69 OCMock, можно отклонить вызов метода http://svn.mulle -kybernetik.com / OCMock / trunk / Source / Changes.txt

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

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

В то время как милые издевательства будут просто игнорировать все неожиданные методы можно запретить конкретные методы:

[[mock reject] someMethod]

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

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

19 голосов
/ 03 мая 2010

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

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

    [mock forbiddenMethod];
    [mock verify]; //should fail
}
7 голосов
/ 27 апреля 2016

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

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

    // exception will raise
    [mock forbiddenMethod];
3 голосов
/ 18 апреля 2013

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

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

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

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

[[[_myPartialMock stub] andDoFail] unexpectedMethod];
0 голосов
/ 29 августа 2017

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

OCMReject([mock someMethod]);
[mock testMethod];
0 голосов
/ 24 февраля 2011

Вы также можете попробовать что-то вроде этого, а-ля 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/

...