问题描述
|
我正在学习如何使用Ocmock来测试我的iPhone项目,并且我遇到了这种情况:使用
getHeightAtX:andY:
方法的HeightMap类和使用HeightMap
的Render类。我正在尝试使用一些HeightMap
模拟进行单元测试Render。这有效:
id mock = [OcmockObject mockForClass:[Chunk class]];
int h = 0;
[[[mock stub] andReturnValue:Ocmock_VALUE(h)] getHeightAtX:0 andY:0];
当然,仅适用于x=0
和y=0
。我想使用“平坦”高度图进行测试。这意味着我需要做这样的事情:
id chunk = [OcmockObject mockForClass:[Chunk class]];
int h = 0;
[[[chunk stub] andReturnValue:Ocmock_VALUE(h)] getHeightAtX:[OCMArg any] andY:[OCMArg any]];
但这会引发两个编译警告:
警告:传递\'getHeightAtX:andY:\'
的参数1会使指针的整数不进行强制转换
和运行时错误:
调用了意外的方法:\'getHeightAtX:0 andY:0 stubbed: getHeightAtX:15545040 andY:15545024\'
我想念什么?我没有办法向这个模拟游戏传递9英镑。
解决方法
OCMock当前不支持原始参数的松散匹配。尽管似乎已停滞不前,但OCMock论坛上正在讨论有关支持此更改的潜在更改。
我发现的唯一解决方案是以我知道将要传递的原始值的方式来构造测试,尽管这远非理想。
, 自问这个问题已经有一段时间了,但我自己遇到了这个问题,在任何地方都找不到解决方案。 OCMock现在支持
ignoringNonObjectArgs
,因此以expect
为例
[[[mockObject expect] ignoringNonObjectArgs] someMethodWithPrimitiveArgument:5];
5实际上什么也没做,只是一个填充值
, 请改用OCMockito。
它支持原始参数匹配。
例如,在您的情况下:
id chunk = mock([Chunk class]);
[[given([chunk getHeightAtX:0]) withMatcher:anything() forArgument:0] willReturnInt:0];
, 除了安德鲁·帕克(Andrew Park)的答案之外,您还可以使其更一般,更漂亮:
#define OCMStubIgnoringNonObjectArgs(invocation) \\
({ \\
_OCMSilenceWarnings( \\
[OCMMacroState beginStubMacro]; \\
[[[OCMMacroState globalState] recorder] ignoringNonObjectArgs]; \\
invocation; \\
[OCMMacroState endStubMacro]; \\
); \\
})
您可以像这样使用它:
OCMStubIgnoringNonObjectArgs(someMethodParam:0 param2:0).andDo(someBlock)
您可以做同样的期望。这种情况是作为主题启动器请求的存根。已使用OCMock 3.1.1进行了测试。
, 尽管相当hacky,但是使用期望来存储传递的块以供稍后在测试代码中调用的方法对我有用:
- (void)testVerifyPrimitiveBlockArgument
{
// mock object that would call the block in production
id mockOtherObject = OCMClassMock([OtherObject class]);
// pass the block calling object to the test object
Object *objectUnderTest = [[Object new] initWithOtherObject:mockOtherObject];
// store the block when the method is called to use later
__block void (^completionBlock)(NSUInteger value) = nil;
OCMExpect([mockOtherObject doSomethingWithCompletion:[OCMArg checkWithBlock:^BOOL(id value) { completionBlock = value; return YES; }]]);
// call the method that\'s being tested
[objectUnderTest doThingThatCallsBlockOnOtherObject];
// once the expected method has been called from `doThingThatCallsBlockOnOtherObject`,continue
OCMVerifyAllWithDelay(mockOtherObject,0.5);
// simulate callback from mockOtherObject with primitive value,can be done on the main or background queue
completionBlock(45);
}
, 您可以这样:
id chunk = OCMClassMock([Chunk class])
OCMStub([chunk ignoringNonObjectArgs] getHeightAtX:0 andY:0]])
有关更多信息,请访问:http://ocmock.org/reference/#argument-constraints