使用 `OCMock` 进行单元测试

3
我希望使用OCMock编写单元测试覆盖MYImageLoader类。其中一个测试可以确保下载图像时,将文件从NSURLSessionDownloadTask回调返回的位置复制到临时位置。在编写良好的单元测试时,我不想测试方法的具体实现细节。因此,我在MYImageLoader类的构造函数中传递了NSFileManager类的模拟对象。但是,有几种同样可能用于复制文件的NSFileManager方法:
- (BOOL)copyItemAtURL:(NSURL *)srcURL toURL:(NSURL *)dstURL error:(NSError **)error;
- (BOOL)moveItemAtURL:(NSURL *)srcURL toURL:(NSURL *)dstURL error:(NSError **)error;
- (BOOL)copyItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error;
- (BOOL)moveItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error;

那么这里的最佳实践是什么呢?我不希望我的单元测试决定我应该在方法实现中使用哪些方法,只是为了确保测试通过。

OCMock 中是否有类似“期望这个或这个或这个”的功能呢?

或者您可以提供一个不同的方法吗?


你能否在你的方法完成后测试文件是否存在? - Ben Flynn
但这就是为什么我模拟NSFileManager,而不是创建一个实际的文件,因为只是想看看是否被要求这样做。如果在每个测试中都创建一个实际的文件,我担心我的测试速度会变慢。 - dariaa
1个回答

1
如果不是期望,而是模拟,且添加一个andDo块以在发生时设置一个布尔值,会怎样呢?
__block BOOL didMove = NO;
OCMStub([fileManagerMock copyItemAtUrl:OCMOCK_ANY toUrl:OCMOCK_ANY error:[OCMArg setTo:nil]]).andDo(^(NSInvocation *invocation) { didMove = YES; }));

如果您对每个进行此操作,然后在之后断言它是YES,那么可能会解决您想要做的事情。

是的,那就是我最终所做的。我只是想知道是否有更优雅的解决方案。谢谢你,如果没有其他建议,我一会儿就会接受你的答案。 - dariaa
1
我认为这取决于你在白盒测试和黑盒测试之间划分的界限。如果一个方法说它将文件写入磁盘,在黑盒的角度来看,你能做的最好的就是检查那个文件,对吧?知道它以某种方式使用NSFileManager真的有什么不同于知道它如何使用它吗?也许有,但也可能没有。或者,你可以将写入文件的方法包装在自己的方法中,明确说明它调用了哪个NSFileManager进行写入。不过,如果有人对此有其他想法,我会很感兴趣。 - Ben Flynn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接