OCMock类类别无法正常工作

时间:2019-01-15 11:27:08

标签: ios objective-c ocmock quick-nimble

我具有以下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];
    });

为什么resultImagenil。 注意:
我不是OCMock的专家,所以我可能做的有些天真。
如果您要处理核心数据外部存储,则UIImage imageWithData可能会引发异常。

1 个答案:

答案 0 :(得分:0)

您正在模拟方法+ imageMightThrowWithData:error :,但随后尝试在模拟实现中调用模拟方法。我不确定结果是什么,但是如果失败并返回nil,也不会令我感到惊讶。您正在使用OCMStrictClassMock,这意味着您不能再调用UIImage上的任何类方法,包括您自己的方法。

但是,由于imageData已经作为参数提供,因此您根本不需要模拟它-只需传递要测试的参数即可。实际上,您也不需要模拟+ imageWithData:。只需传递您似乎已经拥有的imageData即可。我可能会看到模拟+ imageWithData:与非严格模拟一起抛出,以测试这种情况(如果您不能轻易获得将导致Apple方法首先抛出的NSData),但是为此测试我完全没有必要使用OCMock。因此,只需删除OCMStrictClassMock和两个OCMStub调用,我认为它应该可以工作。

如果您要模拟imageWithData:方法以便返回更快,我想应该可以,但是使用OCMClassMock而不是严格的方法,这样您仍然可以测试自己的类方法,然后不要使用OCMStub您要测试的方法。