gpt4 book ai didi

java - 为什么 mock 私有(private)领域是不好的?

转载 作者:行者123 更新时间:2023-12-02 11:09:57 25 4
gpt4 key购买 nike

假设我有一些 A 类,它内部依赖于 B 类,它在私有(private)字段中初始化:

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);
}
}

现在我需要为公共(public)方法 doSomeProcessing() 创建单元测试,但我不想将任何内容写入光盘,因为这是一项耗时的操作。因此我必须模拟 bufferedWriter

现在我有两种可能性:

  1. 允许类 SomeSpecialProcessing 使用 setter 或构造函数在外部设置 bufferedWriter,然后在单元测试中我会将模拟传递到该字段。
  2. 在单元测试中,我将使用反射模拟bufferedWriter

现在我更喜欢使用反射,但很多人说这是不好的做法,并建议将bufferedWriter添加到构造函数或setter中。但我认为仅仅因为单元测试而暴露类的内部字段是愚蠢的。

如何解决此类问题?

最佳答案

But I think it's stupid to exposure internal fields of class just because of Unit tests

它不仅使您的代码更容易进行单元测试,而且总体上使您的代码更加灵活。

目前你的类(class)非常不灵活。它可以进行一些处理并保存到名为 something.log 的单个文件中。它以一种非常特定的方式(使用 BufferedWriter)写入它,这可能是也可能不是写入特定输出的最有效方式。基本上,您正在从类(class)用户手中夺取控制权。

通过将您的依赖项推广到任何可以在某处写入字符串的东西,您可以提高类的灵 active ,并允许其用户自己决定提供哪些最佳依赖项来满足他们的需求要求。

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 个用例:写入实际日志,而不执行任何操作。在某种程度上,您已经需要这种灵 active 。您想通过使用反射来回避这个问题,并声称它同样好。

问题是它并不那么好。基于反射的测试将变得更加脆弱。想重构私有(private)字段的名称吗?哦,看,我已经破坏了我的测试。想要更改内部实现以不使用 BufferedWriter 吗?哦,看,我已经破坏了我的测试。

关于java - 为什么 mock 私有(private)领域是不好的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50678127/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com