xcode 将原语传递给 OCMock 的存根
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6325289/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Passing primitives to an OCMock's stub
提问by Eduardo Costa
I'm learning how to use OCMock to test my iPhone's project and I have this scenario: a HeightMap class with a getHeightAtX:andY:
method, and a Render class using HeightMap
. I'm trying to unit test Render using some HeightMap
mocks. This works:
我正在学习如何使用 OCMock 来测试我的 iPhone 项目,我有这个场景:一个 HeightMap 类和一个getHeightAtX:andY:
方法,一个 Render 类使用HeightMap
. 我正在尝试使用一些HeightMap
模拟对 Render 进行单元测试。这有效:
id mock = [OCMockObject mockForClass:[Chunk class]];
int h = 0;
[[[mock stub] andReturnValue:OCMOCK_VALUE(h)] getHeightAtX:0 andY:0];
Of course, works only for x=0
and y=0
. I want to test using a "flat" height map. This means I need to do something like this:
当然,仅适用于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]];
But this raises two compilation warnings:
但这会引发两个编译警告:
warning: passing argument 1 of
'getHeightAtX:andY:'
makes integer from pointer without a cast
警告:
'getHeightAtX:andY:'
从指针传递参数 1 of使整数没有强制转换
and a runtime error:
和运行时错误:
unexpected method invoked:
'getHeightAtX:0 andY:0 stubbed: getHeightAtX:15545040 andY:15545024'
调用了意外的方法:
'getHeightAtX:0 andY:0 stubbed: getHeightAtX:15545040 andY:15545024'
What am I missing? I found no way to pass a anyValue
to this mock.
我错过了什么?我发现无法将 a 传递anyValue
给这个模拟。
采纳答案by Christopher Pickslay
OCMock doesn't currently support loose matching of primitive arguments. There's a discussion about potential changes to support this on the OCMock forums, though it seems to have stalled.
OCMock 目前不支持原始参数的松散匹配。在 OCMock 论坛上有关于支持此功能的潜在更改的讨论,尽管它似乎已停止。
The only solution I've found is to structure my tests in such a way that I know the primitive values that will be passed in, though it's far from ideal.
我发现的唯一解决方案是以这样一种方式构建我的测试,即我知道将传入的原始值,尽管它远非理想。
回答by Andrew Park
It's been awhile since this question has been asked but I ran into this issue myself and couldn't find a solution anywhere. OCMock now supports ignoringNonObjectArgs
so an example of an expect
would be
自从提出这个问题以来已经有一段时间了,但我自己遇到了这个问题并且在任何地方都找不到解决方案。OCMock 现在支持ignoringNonObjectArgs
所以一个例子expect
是
[[[mockObject expect] ignoringNonObjectArgs] someMethodWithPrimitiveArgument:5];
the 5 doesn't actually do anything, just a filler value
5 实际上没有做任何事情,只是一个填充值
回答by yonix
回答by Alex
In addition to Andrew Parkanswer you could make it a little bit more general and nice looking:
除了Andrew Park 的回答之外,您还可以使它更通用和美观:
#define OCMStubIgnoringNonObjectArgs(invocation) \
({ \
_OCMSilenceWarnings( \
[OCMMacroState beginStubMacro]; \
[[[OCMMacroState globalState] recorder] ignoringNonObjectArgs]; \
invocation; \
[OCMMacroState endStubMacro]; \
); \
})
The you can use it like that:
你可以这样使用它:
OCMStubIgnoringNonObjectArgs(someMethodParam:0 param2:0).andDo(someBlock)
You can do the same for expecting. This case is for stubbing as topic starter request. It was tested with OCMock 3.1.1.
你可以为期待做同样的事情。这种情况用于存根作为主题启动器请求。它使用 OCMock 3.1.1 进行了测试。
回答by Matt Robinson
Despite being fairly hacky, the approach of using expectations to store the passed block to call later in the test code has worked for me:
尽管相当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);
}
回答by Tan Vu
You could do like this:
id chunk = OCMClassMock([Chunk class])
OCMStub([chunk ignoringNonObjectArgs] getHeightAtX:0 andY:0]])
你可以这样做:
id chunk = OCMClassMock([Chunk class])
OCMStub([chunk ignoringNonObjectArgs] getHeightAtX:0 andY:0]])
Readmore at: http://ocmock.org/reference/#argument-constraints