目前在生产代码中,我有这样的功能
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))
这种不必要的开销只是为了能够使代码可测试吗?或者这是可以接受的吗?
最佳答案
修改您的代码以使其可测试是完全有效的。测试只是您代码的另一个客户端,因此会提供有关代码可用性的反馈。
另一方面,为了使反馈具有建设性,测试必须遵守一些规则。例如它应该测试代码的行为而不是它的内部。
现在,对于实际测试,您有更多选择。
- 最直接的方法是为其依赖项使用测试替身。您提到 functionA 是最终的,因此不能对其进行模拟。它可以。虽然都不是理想的解决方案 Mockito 2.+和 PowerMock支持模拟
final classes
。 - 更简洁的方法是聆听您的测试。您的测试告诉您您的代码存在设计问题。也许你可以解决这些问题。例如,您可以尝试分离线程和执行逻辑,以便对其进行测试。或者,您可以引入一个接口(interface),使依赖项可模拟。
关于java - 将生产代码修改为可测试/仅用于测试目的是最佳做法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55606889/