【发布时间】:2012-11-07 11:10:02
【问题描述】:
我正在尝试使用 OCMock 的存根 andDo 方法编写一段代码。
在这种情况下,UIImageView 扩展类正在测试中。我想检查扩展调用 [self setImage:] 的参数是否为非零(稍后将使用其他图像比较)。
当使用 OCMock 的 andDo 方法时,测试在块完成后崩溃并出现 EXC_BAD_ACCESS。
id mockView = [OCMockObject mockForClass:[UIImageView class]];
[[[mockView stub] andDo:^(NSInvocation *invocation)
{
UIImage *img;
[invocation getArgument:&img atIndex:2]; <---- line causing the exception
somebodySetImage |= (img != nil);
}] setImage:OCMOCK_ANY];
[mockView do_something_that_calls_setImage];
我目前找到的唯一解决方案是使用 andCall 而不是 andDo,但这会使测试复杂化。
我可以使用 andDo 避免崩溃吗?
更新 好吧,我将尝试在这里举一个更好的例子: 这是新的测试代码:
- (void)testDownloadingThumbnail
{
PInfo *_sut = [[PInfo alloc] init];
__block id target = nil;
id mock = [OCMockObject mockForClass:[NSOperationQueue class]];
[[[mock expect] andDo:^(NSInvocation *inv)
{
NSInvocationOperation *op;
[inv getArgument:&op atIndex:2];
target = [[op invocation] target]; /* replacing this line with STAssert does not help either */
}] addOperation:OCMOCK_ANY];
[_sut setDownloadQueue:mock];
[_sut startDownloadingImagesAsync:YES];
[mock verify];
STAssertEqualObjects(target, _sut, @"invalid op target");
}
这是经过测试的代码(来自 PInfo 的单一方法):
- (void)startDownloadingImagesAsync:(bool)isThumbnailImg
{
NSInvocationOperation *inv;
inv = [[NSInvocationOperation alloc] initWithTarget:self
selector:@selector(loadThumbnailWorker:)
object:nil];
[[self downloadQueue] addOperation:inv];
}
代码在退出 startDownloadingImagesAsync 时仍然会崩溃,并带有 EXC_BAD_ACCESS。 如果我在 andDo 块内添加断点,我会看到控件到达该点并通过 getArgument 检索正确的对象。
然而,如果我在块内使用 getArgument,无论我尝试做什么,它都会崩溃。
附:感谢您的帮助。
【问题讨论】:
-
你能详细说明
[mockView do_something_that_calls_setImage];的意思吗? -
大致如下:-(void)do_something_that_calls_setImage { [self setImage:[UIImage imagedNamed:@"f.png"]; }
-
我认为您需要发布更多代码。您不应该直接在
mockView上调用方法——它只是模拟的代理。我必须假设您的最后一行是对引用mockView的其他对象的调用。如果您能澄清或解释您在测试中要达到的目标,我可能会提供帮助。 -
嗨,@ChristopherPickslay。我以某种方式错过了通知。在这种情况下,我正在尝试测试 mockView 的另一种方法:do_something_that_calls_setImage。该方法使用 mockView 自己的 setImage 方法。但这在您指定的情况下也会失败:在包含对 mockView 的引用的对象上调用 _do_something_that_calls_setImage_。我无法使用 andDo 的参数。尝试这样做总是会导致 EXC_BAD_ACCESS。
-
只是好奇,你在用ARC吗?
标签: iphone ios xcode ocunit ocmock