Подтвердить что ты не робот

Как я могу использовать OCMock для проверки того, что метод никогда не вызывается?

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

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

Ответ 1

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

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

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

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

[[mock reject] someMethod]

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

Цитата из: http://www.mulle-kybernetik.com/software/OCMock/#features

Ответ 2

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

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

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

Ответ 3

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

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

    // exception will raise
    [mock forbiddenMethod];

Ответ 4

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

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

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

Я использую его следующим образом:

[[[_myPartialMock stub] andDoFail] unexpectedMethod];

Ответ 5

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

Ответ 6

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

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