我有一个关于测试类(如转换器)的问题。 可以说我有一个从EntityA到EntityB的转换器。转换器看起来像这样:
public EntityB convert(EntityA){
//call interal methods
return B.
}
private xy internalMethod1(...){
//call other interal Method
}
private xy internalMethod2(...){
....
}
private xy internalMethod3(...){
....
}
private xy internalMethod4(...){
....
}
转换器具有一个公共方法和4个内部方法来转换实体。
我应该如何测试?
选项1 我仅测试公共方法,并通过不同的示例输入涵盖了internalMethods中的所有情况。
优点: 仅测试“接口”。不知道内部结构。 内部重构非常容易,不需要在测试中进行任何更改。
缺点: 可能是测试所有案例的真正大型测试,可能尚不清楚。 每个输入都必须通过所有方法。
选项2 我为我的公共方法和私有方法编写测试。 (一些测试框架可以访问私有方法,例如powermock或spock(groovy)) 我单独测试每种方法,并模拟其他所有内部方法。
优点: 真正的小型测试,仅测试方法本身并模拟所有其他方法。
缺点: 我知道它是如何在内部实现的,如果我在内部调用结构上重构某些方法,某些方法名或某些内容,则必须更改测试
选项3 我写了一些新的类来做内部工作并有公共方法
优点: 测试可能更清晰,并且仅针对特殊班级。
缺点: 一项转换任务需要更多类。
请帮助我,这里的最佳做法是什么。 也许一些良好的链接/提示。 谢谢您的宝贵时间。
答案 0 :(得分:1)
您提出的观点是正确的,但我认为您可能无法正确估算其权重。
编写脆性测试(与实现代码耦合的测试)使刚性代码库难以更改。由于编写测试的初衷是要快速进行,所以这适得其反。
这就是为什么您仅通过API编写测试的原因-它使测试与实现分离。正如您所说的那样,这可能会使编写测试变得更加困难,但是值得付出的努力是值得的,因为您将获得安全性并能够轻松进行重构。
选项3在您看到代码气味时起作用,其中某些测试仅覆盖部分代码,而其他测试仅覆盖代码的其他部分。这通常意味着可能需要提取一个协作者。当某些内部函数仅使用某些参数而其他不使用某些参数时,尤其如此。另外,当有代码重复之类的时候。
我的建议是,使用重构1中描述的方式编写它,然后在重构阶段提取代码(如果需要)。