模拟 UIImagePNGRepresentation

mocking UIImagePNGRepresentation

我正在尝试使用 OCMock 模拟 UIImagePNGRepresentation。 UIImagePNGRepresentation 接受 UIImage 和 returns NSData。

但似乎不能将其模拟为普通函数。

下面是我试过的,但是编译不了

id mockAlbumArt = [OCMockObject niceMockForClass:[UIImage class]];
id mockImageData = [OCMockObject niceMockForClass:[NSData class]];

id uiimageMock = [OCMockObject niceMockForClass:[UIImage class]];
[[[uiimageMock expect] andReturn:mockImageData] UIImagePNGRepresentation:mockAlbumArt];

如果您查看 UIImage 的 header,UIImagePNGRepresentation 定义为:

UIKIT_EXTERN  NSData * __nullable UIImagePNGRepresentation(UIImage * __nonnull image);                               // return image as PNG. May return nil if image has no CGImageRef or invalid bitmap format

有没有人做过函数的mocking?任何帮助将不胜感激,谢谢。

你是对的,普通函数不能那样被模拟。

OCMock 和 OCMockito 等模拟库提供了一种存根和验证方法调用的方法。 UIImagePNGRepresentation 不是一个方法,它是一个独立的 C 函数。

那么如何更换测试呢?不要直接调用它,而是通过一个函数指针。对于正常使用,将 UIImagePNGRepresentation 分配给您的指针。为了测试,分配一个您定义的函数。

使用 Facebook 库 fishhook 可以轻松实现与此类似的模拟 C 函数。 https://github.com/facebook/fishhook

在测试文件中写一个替代方法:

NSData * __nullable swizzled_UIImagePNGRepresentation(UIImage * __nonnull image)
{
    return [NSData data];
}

然后我们从测试函数重新绑定符号,以便调用我们的方法而不是原始方法。有点像 method swizzling。

-(void)testAlbumArt
{
     rebind_symbols((struct rebinding[1]){{"UIImagePNGRepresentation", swizzled_UIImagePNGRepresentation}}, 1); 
    ....continue and expect [NSData data] when you call UIImagePNGRepresentation...
}