我具有以下UIImage
类别:
@implementation UIImage (Exception)
+ (nullable UIImage *)imageCanThrowWithData:(NSData *)data error:(NSError **)errorPtr
{
UIImage *image = nil;
@try {
image = [self imageWithData:data];
} @catch (id exception) {
*errorPtr = [NSError errorWithDomain:@"mydomain" code:0 userInfo:nil];
}
return image;
}
@end
然后我尝试使用OCMock对此进行测试:
摘录自安装程序 ...
beforeEach(^{
NSString* labelPath = [[NSBundle mainBundle] pathForResource:@"image" ofType:@"jpg"];
imageData = [NSData dataWithContentsOfFile:labelPath];
image = [UIImage imageWithData:imageData];
});
it(@"should return the image if no exception is thrown", ^{
id mock = OCMStrictClassMock([UIImage class]);
NSError *error = nil;
OCMStub([mock imageWithData:OCMOCK_ANY]).andReturn(image);
OCMStub([mock imageMightThrowWithData:imageData error:&error]).andReturn([UIImage imageMightThrowWithData:imageData error:&error]);
UIImage* resultImage = [[mock expect] imageMightThrowWithData:imageData error:&error];
expect(resultImage).toNot(beNil());
expect(error).to(beNil());
[mock stopMocking];
});
为什么resultImage
是nil
。
注意:
我不是OCMock的专家,所以我可能做的有些天真。
如果您要处理核心数据外部存储,则UIImage imageWithData可能会引发异常。
答案 0 :(得分:0)
您正在模拟方法+ imageMightThrowWithData:error :,但随后尝试在模拟实现中调用模拟方法。我不确定结果是什么,但是如果失败并返回nil,也不会令我感到惊讶。您正在使用OCMStrictClassMock,这意味着您不能再调用UIImage上的任何类方法,包括您自己的方法。
但是,由于imageData已经作为参数提供,因此您根本不需要模拟它-只需传递要测试的参数即可。实际上,您也不需要模拟+ imageWithData:。只需传递您似乎已经拥有的imageData即可。我可能会看到模拟+ imageWithData:与非严格模拟一起抛出,以测试这种情况(如果您不能轻易获得将导致Apple方法首先抛出的NSData),但是为此测试我完全没有必要使用OCMock。因此,只需删除OCMStrictClassMock和两个OCMStub调用,我认为它应该可以工作。
如果您要模拟imageWithData:方法以便返回更快,我想应该可以,但是使用OCMClassMock而不是严格的方法,这样您仍然可以测试自己的类方法,然后不要使用OCMStub您要测试的方法。