假设我有一个类Foo
,它只使用类Bar
的实例进行实例化:
public Foo(Bar x) {
this.a = x.a();
this.b = x.b();
...
}
现在我想测试Foo
,进一步假设难以创建具有所需状态的Bar
实例。作为附加约束,字段a, b, ...
被声明为final,因此这些字段的setter不可用。
可能是在Foo中创建一个额外的构造函数:
protected Foo(A a, B b, ...) {
this.a = a;
this.b = a;
...
}
此构造函数仅在测试期间使用,我将在此构造函数的注释中声明。
问题:这是代码味吗?
我想到的另一个解决方案是嘲笑Bar
。想知道它是否是这种情况下的最佳做法?
答案 0 :(得分:9)
模拟栏更有可能被视为最佳实践。你应该可以创建一个MockBar,这样就可以了
Foo foo = new Foo(new MockBar(a, b));
答案 1 :(得分:4)
我可能会认为这种形式很差,但如果它有效,它就有效。一个更好的解决方案是创建一个TestBar
类,它是Bar
的子类,并覆盖Bar
中的方法。正如你在问题中提到的那样,我猜这几乎是在嘲笑这个对象。它更清晰,允许您定义测试驱动程序可以包含的不同Bar
实现。
答案 2 :(得分:0)
Hmmmmmm。
也就是说,您说的是什么 种类 ?如果要测试的东西是单独的方法,或者要测试的东西是我们可以得到的最类似于生产的环境中的整个应用程序,那么在创建环境所需的条件上有很大的不同对于要测试的东西。 “如我们所愿,就像生产一样”意味着您 不应执行任何旨在使测试成功的代码。在针对应用程序较小部分的测试中,这几乎没有什么问题。 “测试”并不总是与“测试”相同。测试汽车防滚架意味着像测试一样可以承受是否能够承受锡所承受的扭矩。在测试整辆车时,您不会做同样的事情。测试零件与测试整个装配体是不同的。