我正在尝试使用 OCMock 的 stub 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];
}
使用 EXC_BAD_ACCESS从startDownloadingImagesAsync退出时,代码仍会崩溃。如果我在andDo块中添加断点,我会看到控件到达该点并通过getArgument检索正确的对象。
然而,如果我在块内使用getArgument,无论我尝试做什么,它都会崩溃。
PS感谢您的帮助。