最好将生产代码修改为可测试的/仅用于测试目的?

时间:2019-04-10 07:22:44

标签: java testing

目前在生产代码中,我具有这样的功能

public void doWork() {
    ... call functionA
    ... call functionB
    ... do other work
}

我必须测试在doWork()中调用functionA之后需要暂停的情况。而且我没有办法在测试框架中暂停

所以我将生产更改为

public void doWork() {
    doWork(new CountdownLatch(0))
}
public void doWork(CountdownLatch latch) {
    ... call functionA with a latch and functionA calls latch.await()
    ... call functionB
    ... do other work
}

现在,我可以创建一个测试案例并使用doWork(new CountdownLatch(1))

进行测试

但是在生产环境中,它将始终调用doWork(),而依次调用doWork(new CountdownLatch(0))

这种不必要的开销仅仅是为了使代码可测试吗?还是可以接受?

1 个答案:

答案 0 :(得分:2)

修改代码以使其可测试是完全有效的。测试只是代码的另一个客户端,因此可以提供有关代码可用性的反馈。

另一方面,要使反馈具有建设性,测试必须遵守一些规则。例如,它应该测试代码的行为,而不是代码的内部。

现在,对于实际测试,您还有更多选择。

  • 最棘手的是对其依赖项使用test double。您提到过functionA是最终的,因此不能被嘲笑。它可以。尽管不是理想的解决方案,Mockito 2.+PowerMock都支持final classes的模拟。
  • 更干净的方法是听您的测试。测试表明您的代码存在设计问题。也许您可以解决这些问题。例如,您可以尝试将线程和执行逻辑分开,以便对其进行测试。或者,您可以引入一个接口来使依赖关系成为可模拟的。