Как я могу использовать 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!");
}
Ответы
Ответ 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];