我有一个只有类方法的类
//FileManager.h
+(void)writeData:(NSData*)data toFile:(NSString*)filePath;
//...
//some more class methods
我在另一个中使用这个类
//AttachmentsRepository.m
-(void)newAttachment:(NSData*)attachmentData{
//some code
NSString * generatedPath = @"/some/generated/path";
[FileManager writeData:attachmentData toFile:generatedPath];
}
现在我正在为 AttachmentRepository 编写测试,并想知道如何注入 FileManager 。
我使用的是“提取和覆盖调用”技术:
//AttachmentsRepository.m
-(void)newAttachment:(NSData*)attachmentData{
//some code
NSString * generatedPath = @"/some/generated/path";
[[self getFileManagerClass] writeData:attachmentData toFile:generatedPath];
}
-(Class)getFileManagerClass{
return [FileManager class];
}
现在,在我的测试中,我只是将getFileManagerClass
存根,以便返回[FakeFileManager class]
什么是更好的解决方案?这是遗留代码,但我们现在正在编写它。应该如何实现 FileManager 依赖。
PS。我想使用假的,因为我想在测试 AttachmentRepository 类时避免写入磁盘。
答案 0 :(得分:0)
来自Michael C. Feathers的“有效使用遗留代码”我发现了“介绍实例代理”技术。
基本上我们复制了我们需要的方法并使它们成为实例方法。他们的身体只是对类/静态方法的调用。然后我们使用实例类作为构造函数的参数或需要使用它的方法。
//FileManager.h
+(void)writeData:(NSData*)data toFile:(NSString*)filePath;
-(void)writeData:(NSData*)data toFile:(NSString*)filePath;
//...
//FileManager.m
-(void)writeData:(NSData*)data toFile:(NSString*)filePath;{
[FileManager writeData:data toFile:filePath];
}
在 AttachmentsRepository :
中//AttachmentsRepository.m
-(instance) initWithFileManager:(FileManager *)fileManager{
if(self = [super init]){
_fileManager = fileManager
}
return self;
}
-(void)newAttachment:(NSData*)attachmentData{
//some code
NSString * generatedPath = @"/some/generated/path";
[self.fileManager writeData:attachmentData toFile:generatedPath];
}
结论似乎是 FileManager 类不应该有类/静态方法,而是实例方法,而不是在开始时实现它。
所有这些让我感到尴尬 - 使得类/静态的方法可以在实例级别上进行。