OCMock: OCMPartialMock 对象调用实际方法而不是存根

Posted

技术标签:

【中文标题】OCMock: OCMPartialMock 对象调用实际方法而不是存根【英文标题】:OCMock: OCMPartialMock object calls the actual method rather than the stub 【发布时间】:2016-05-26 11:48:45 【问题描述】:

我在一个类中有 2 个方法,其中一个简单地使用特定参数调用另一个。方法如下:

-(void)loadAllFollowersForUser:(NSUInteger)userID withResponseHandler:(_Nullable CompletionHandler)handler 
[self loadFollowersForUser:userID
                fromOffSet:0
                   toLimit:100000
       withResponseHandler:handler];


-(void)loadFollowersForUser:(NSUInteger)userID fromOffSet:(NSInteger)offset toLimit:(NSInteger)limit withResponseHandler:(_Nullable CompletionHandler)handler 
    NSLog(@"Actual loadFollowersForUser method got called!");

我正在尝试 TDD 并且一直在使用 OCMock。我有以下测试只是测试 loadAllFollowers 在内部调用另一个方法

- (void)testLoadAllFollowersCallsLoadFollowers 
    id partialMockSUT = OCMPartialMock(self.sut);

    OCMExpect([partialMockSUT loadFollowersForUser:[OCMArg any]
                                         fromOffSet:[OCMArg any]
                                            toLimit:[OCMArg any]
                                withResponseHandler:[OCMArg any]]);

    [partialMockSUT loadAllFollowersForUser:123
                           withResponseHandler:^(BOOL success, id response, NSError *error) 

                           ];

    OCMVerifyAll(partialMockParser);


我使用的是部分模拟,因为我只想存根 loadFollowersForUser 方法并调用 loadAllFollowers 方法的实际实现。这几乎完全一样,但我的测试总是未能达到预期,我在控制台中看到了 NSLog。

我尝试过的事情:

    我尝试添加其他临时方法来验证部分模拟的行为,它们的性能完全符合预期 This 问题表明我正在尝试做的事情应该很有可能 我已尝试在 OCMExpect 与 OCMock 文档内联之后为该方法添加 OCMStub。请参阅this page 上的 10.2

我不确定传入的块是否有问题,或者方法返回类型是否为 void,我对预期没有任何行动。

【问题讨论】:

快速浏览 ocmock.org/reference/#argument-constraints 的 OCMock 文档会发现“不能使用任何占位符忽略既不是对象也不是指针或选择器的参数”和一种解决方法。这可能是问题所在,因为那里有标量参数。 谢谢!这似乎奏效了。奇怪的是,它抛出的异常是关于未满足期望,而不是抛出关于任何约束与标量值的警告/错误。这让我难过了好几个小时。您能否将其发布为答案,经过更多测试后我会接受吗? 【参考方案1】:

根据the OCMock docs,[OCMArg any] 占位符只传递“对象、指针和选择器”

这里的问题可能是该方法有标量参数,因此期望失败。文档提出了一种解决方法来处理标量参数,方法是通过调用ignoringNonObjectArgs 来存根方法。所以这可能看起来像:

OCMExpect([[partialMockSUT ignoringNonObjectArgs]
                       loadFollowersForUser:[OCMArg any]
                                 fromOffSet:0  // or any value
                                    toLimit:0  // or any value
                        withResponseHandler:[OCMArg any]]);

不是 100% 确定,因为我自己没有尝试过。

【讨论】:

在我的例子中,用户 ID 是 NSUInteger,这意味着第一个参数也应该是标量。谢谢你的帮助!现在开始测试基于块的完成处理程序:)

以上是关于OCMock: OCMPartialMock 对象调用实际方法而不是存根的主要内容,如果未能解决你的问题,请参考以下文章

OCMock 和 UIViewController

OCMock:存根从不匹配签名

用于模拟对象的 OCMock 无法识别的选择器

OCMock 抛出 EXC_BAD_ACCESS

OCMock 测试分配一个对象并在其上调用一个方法

通过 OCMock 存根覆盖方法