如何为在自身内部实例化协作者的方法编写单元测试?
How to write unit test for method which instantiates collaborators inside itself?
方法代码如下:
- (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];
}
我想我应该模拟 Downloader 和 FileCache 来验证它是否工作正常。
我考虑过像这样更改签名:downloadSomething:(NSString *)url downloader:(Downloader *)downloader cache:(FileCache *)cache
,但在调用此方法之前似乎必须做很多工作,这不是我想要的。
我正在使用 ocmockito。
此外,是否有使编写代码更易于测试的指南?
编辑:2017-01-16 14:54:23
像这样写两个方法是个好主意吗:
- (void)updateCacheWithUrl:(NSString *)url
downloader:(Downloader *)downloader
fileCache:(FileCache *)fileCache; // for testing
- (void)updateCacheWithUrl:(NSString *)url; // call above method with (url, nil, nil);
在方法内部实例化协作者时,会产生紧密耦合。对此进行测试的难度促使我们探索其他设计。
一种方法是将它们传入。这是我通常做的。然后我会制作一个更简单的版本,为生产代码提供默认对象。
但在您的示例中,url
被传递给了 Downloader
,这使得这更难。这表明 downloadSomething:
的当前设计违反了单一职责原则。它在做两件事:下载和缓存。
所以拆分这些职责可能会使事情更容易测试。
方法代码如下:
- (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];
}
我想我应该模拟 Downloader 和 FileCache 来验证它是否工作正常。
我考虑过像这样更改签名:downloadSomething:(NSString *)url downloader:(Downloader *)downloader cache:(FileCache *)cache
,但在调用此方法之前似乎必须做很多工作,这不是我想要的。
我正在使用 ocmockito。
此外,是否有使编写代码更易于测试的指南?
编辑:2017-01-16 14:54:23
像这样写两个方法是个好主意吗:
- (void)updateCacheWithUrl:(NSString *)url
downloader:(Downloader *)downloader
fileCache:(FileCache *)fileCache; // for testing
- (void)updateCacheWithUrl:(NSString *)url; // call above method with (url, nil, nil);
在方法内部实例化协作者时,会产生紧密耦合。对此进行测试的难度促使我们探索其他设计。
一种方法是将它们传入。这是我通常做的。然后我会制作一个更简单的版本,为生产代码提供默认对象。
但在您的示例中,url
被传递给了 Downloader
,这使得这更难。这表明 downloadSomething:
的当前设计违反了单一职责原则。它在做两件事:下载和缓存。
所以拆分这些职责可能会使事情更容易测试。