36

在我的日常工作中,我被Mockito 的never()验证宠坏了,它可以确认永远不会调用模拟方法。

有什么方法可以使用 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!");
}
4

6 回答 6

64

由于 OCMock 的 r69,可以拒绝方法调用http://svn.mulle-kybernetik.com/OCMock/trunk/Source/Changes.txt

不错的模拟/快速失败当在尚未使用期望或存根设置的模拟对象上调用方法时,模拟对象将引发异常。可以通过创建一个“不错的”模拟来关闭这种快速失败模式:

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

虽然 nice mocks 会简单地忽略所有意外方法,但可以禁止特定方法:

[[mock reject] someMethod]

请注意,在快速失败模式下,如果忽略异常,则在调用 verify 时将重新抛出。这使得可以确保可以检测到来自通知等的不需要的调用。

引自: http: //www.mulle-kybernetik.com/software/OCMock/#features

于 2011-04-18T22:58:00.250 回答
19

据我所知,当您调用 verify 并且调用未记录的方法时,OCMock 会自动失败。如果调用了意外的方法也不会抱怨的模拟被称为“漂亮模拟”。

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

    [mock forbiddenMethod];
    [mock verify]; //should fail
}
于 2010-05-02T20:41:42.857 回答
9

从 3.3 版开始,OCMock 具有OCMReject宏。

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

    // exception will raise
    [mock forbiddenMethod];
于 2016-04-27T11:50:29.203 回答
3

您可能还发现有必要确保永远不会在您部分模拟的对象上调用方法。

我为此创建了一个宏:

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

我这样使用它:

[[[_myPartialMock stub] andDoFail] unexpectedMethod];
于 2013-04-18T15:17:35.263 回答
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/

于 2011-02-23T21:10:41.660 回答
0

为了确保你的方法没有被调用,我认为我们必须在被testMethod调用之前做一个断言。因此,请确保OCMReject在运行测试方法之前放置以侦听运行时将触发的方法testMethod

OCMReject([mock someMethod]);
[mock testMethod];
于 2017-08-29T06:58:12.473 回答