假设我有一个类A对内部依赖于类B,它在私有字段中初始化:
class SomeSpecialProcessing {
private BufferedWriter bufferedWriter;
// some other fields
public SomeSpecialProcessing() {
this.bufferedWriter = new BufferedWriter(new FileWriter("something.log"));
}
public String doSomeProcessing() {
// some special calculation
persistToDisc(somethingImportant);
// some special processing
return importantResult;
}
private void persistToDisc(String somethingImportant) {
// this.bufferedWriter.write(str);
}
}
现在我需要为公共方法doSomeProcessing()创建单元测试,但我不想写任何东西到光盘,因为它是耗时的操作。因此,我必须模拟 bufferedWriter 。
现在我有两种可能性如何做到这一点:
现在我更喜欢使用反射,但很多人说这是不好的做法,并建议将 bufferedWriter 添加到构造函数或setter中。但我认为仅仅因为单元测试而暴露类的内部字段是愚蠢的。
如何解决这类问题?
答案 0 :(得分:1)
但我觉得暴露内部课堂领域是愚蠢的 因为单元测试
这不仅使您的代码更容易进行单元测试,而且通常会使您的代码更加灵活。
目前你的课程非常灵活。它可以进行一些处理并持久保存到名为something.log
的单个文件中。它以非常特定的方式(使用BufferedWriter
)编写它,这可能是也可能不是编写特定输出的最有效方式。基本上,你正在控制你的班级用户。
通过将依赖性推广到可以在某处编写字符串的任何内容,您可以提高类的灵活性,并允许其用户自行决定提供哪些最佳依赖项以满足他们的要求要求。
class SomeSpecialProcessing {
private Writer writer;
public SomeSpecialProcessing(Writer writer) {
this.writer = writer;
}
public String doSomeProcessing() {
// some special calculation
persist(somethingImportant);
// some special processing
return importantResult;
}
private void persist(String somethingImportant) {
this.writer.write(str);
}
}
您的类已经有2个用例:写入实际日志,什么都不做。您已经在某种程度上要求这种灵活性。你想通过使用反射来支持这一点,声称它同样好。
问题在于它并不是那么好。基于反射的测试将变得更加脆弱。感觉像重构私人领域的名字?哦,看,我打破了我的考试。感觉像更改内部实现不使用BufferedWriter
?哦,看,我已经破坏了我的考试。