【问题标题】:OCMock stub for method's pass-by-reference argument方法的传递引用参数的 OCMock 存根
【发布时间】:2013-12-16 22:31:47
【问题描述】:

我有一个需要存根的方法。方法如下:

BOOL myMethodWithError:(*__autoreleasing *NSError)error;

所以我模拟了这个对象并试图通过“错误”返回一个 nil。我编码如下。

id mockMyObject = [OCMockObject mockForClass:[MyObject class]];
BOOL retVal = YES;
NSError *error = nil;
[[[mockMyObject stub] andReturn:OCMOCK_VALUE(retVal)] myMethodWithError:&error];

当运行测试并操作模拟对象时,错误引用id似乎发生了变化。所以mock会抛出异常:

OCMockObject[MyObject]:调用的预期方法: myMethodWithError:0xbfffca78

我尝试了许多不同的方法,但每次指针值似乎都会在错误对象传递给导致模拟对象抛出错误的方法时发生变化。

我只需要根据参数的传递引用值测试我的业务规则,但我似乎无法让模拟或测试对象配合。

提前致谢,任何帮助将不胜感激。

【问题讨论】:

  • 我对这个问题有了更清晰的认识。在深入研究了 OCMock 源代码测试后,我发现执行了与我的测试类似的测试。测试使用了 [OCMArg isAnyPointer],它返回一个“void *”。这在 ARC 之前是可以的,但现在 ARC 不允许在 'void *' 和 'NSError *__autoreleasing *' 之间进行隐式转换。这现在似乎是我需要解决的问题。
  • 一个更简单的解决方法是制作一个手动模拟。

标签: unit-testing ios7 tdd ocmock xctest


【解决方案1】:

使用 ignoringNonObjectArgs

[[[[mock stub] andReturnValue:OCMOCK_VALUE((BOOL){YES})] ignoringNonObjectArgs] myMethodWithError:NULL];

来自http://ocmock.org/features/

既不是对象也不是指针或选择器的参数不能 使用任何占位符忽略。不过,有可能告诉 模拟忽略调用中的所有非对象参数:

[[[mock expect] ignoringNonObjectArgs] someMethodWithIntArgument:0] 

在这 如果模拟将接受 someMethodWithIntArgument 的任何调用: 无论实际通过什么参数。如果方法有对象 参数以及非对象参数,对象参数可以 仍然像往常一样使用 OCMArg 上的方法进行约束。

奖励答案

这也可以解决您的问题:

[[[mock stub] andReturnValue:OCMOCK_VALUE((BOOL){YES})] myMethodWithError:[OCMArg setTo:nil]];

【讨论】:

    【解决方案2】:

    除了 Ben 在他的回答中提到的解决方案(我只测试了基于 ignoringNonObjectArgs 的解决方案,它工作正常),我更喜欢使用 [OCMArg anyPointer] 和适当的演员:

    [[[myMock stub] andReturn:something] someMethod:(NSError * __autoreleasing *)[OCMArg anyPointer]];
    

    【讨论】:

    • 哈!不知何故,我一直以铿锵不喜欢的方式误投anyPointer,并错过了明显的那个。 =)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-19
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多