简体   繁体   中英

How to write unit test for method which instantiates collaborators inside itself?

Method code like so:

- (void)downloadSomething:(NSString *)url {
    Downloader *downloader = [[Downloader alloc] initWithUrl:url];
    NSData *data = [downloader download];
    FileCache *cache = [[FileCache alloc] initWithFile:@"download.cache"];
    cache.data = data;
    [cache save];
}

I think I should mock Downloader and FileCache to verify if it works well. I have thought about change signature like that: downloadSomething:(NSString *)url downloader:(Downloader *)downloader cache:(FileCache *)cache , but it seem to have to do much work before call this methods, that's not what I want.

I am using ocmockito.

Besides, is there a guide to make writing code more testable ?


edit: 2017-01-16 14:54:23

Is this a good idea to write two method like:

- (void)updateCacheWithUrl:(NSString *)url 
                downloader:(Downloader *)downloader 
                 fileCache:(FileCache *)fileCache; // for testing
- (void)updateCacheWithUrl:(NSString *)url; // call above method with (url, nil, nil);

When a collaborator is instantiated inside a method, this creates tight coupling. The difficulty of testing this leads us to explore other designs.

One way is to pass them in. This is what I'd normally do. Then I would make a simpler version that provides default objects for production code.

But in your example, the url is passed to the Downloader , which makes this harder. This suggests that the current design of downloadSomething: violates the Single Responsibility Principle. It's doing two things: downloading, and caching.

So splitting up these responsibilities would probably make things easier to test.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM