3

I want to cover MYImageLoader class with unit tests using OCMock. On of the tests makes sure that when it downloads an image it copies the file from the location returned in a NSURLSessionDownloadTask callback to a temporary location. And here I am trying to write a good unit test I do not want to test method implementation details. So I pass a mock of a NSFileManager class in the constructor of MYImageLoader class. But there are several equally possible to use NSFileManager methods to copy a file:

- (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;

So what would be the good practice here? I don’t want my unit tests to determine which methods I should use in the method implementation just to make sure the test passes.

Is there anything like expect this or this or this in OCMock?

Or may be you can advise a different approach?

dariaa
  • 6,285
  • 4
  • 42
  • 58
  • Could you just test for the presence of the file after your method completes? – Ben Flynn Jul 01 '15 at 15:43
  • But that's why I mock `NSFileManager`, not to create an actual file because just to see if it was asked to do so. If I create an actual file in every test I'm afraid my tests will not run fast. – dariaa Jul 02 '15 at 07:45

1 Answers1

1

What if, instead of expecting, you just mock, but add an andDo block that sets a bool when it happens?

__block BOOL didMove = NO;
OCMStub([fileManagerMock copyItemAtUrl:OCMOCK_ANY toUrl:OCMOCK_ANY error:[OCMArg setTo:nil]]).andDo(^(NSInvocation *invocation) { didMove = YES; }));

If you do that for each one and then assert it is YES afterward, that might take care of what you want to do.

Ben Flynn
  • 18,524
  • 20
  • 97
  • 142
  • Yes, that's what I ended up doing. I was just wondering if there is a more elegant solution. Thank you and I will accept your answer in a while if there are no other suggestions. – dariaa Jul 03 '15 at 14:13
  • 1
    I think it comes down to where you draw the line between white box and black box testing. If a method says that it writes a file to disk, from a black box perspective, the best you can do is check for that file, yes? Is knowing it uses NSFileManager in some way really any different from knowing exactly how it uses it? Maybe, but maybe not. Alternatively, you could wrap the write-to-file method in your own method that explicitly states what NSFileManager it calls for writing. I'd be interested, though, if someone has other thoughts on this. – Ben Flynn Jul 06 '15 at 02:04