由于我的应用程序域的数据结构到最近变得非常复杂,我开始阅读模拟对象。很快出现了一个简单的问题,但迄今为止,答案已经证明是相当头痛的。所以这里有云:如何在单元测试中使用模拟手法避免误报?
我们有一类“富”与“酒吧”作为其中的一个方法:
class Foo {
public String bar(int i){
if(i == 1) return "arrr!";
}
}
而且我们有一个类海盗调用Foo.bar(1);在其中的一个方法:
class Pirate {
public String yell(){
Foo foo = new Foo();
return foo.bar(1);
}
现在我们嘲笑Foo类的海盗类的单元测试,因为富恰好有其他依赖过多:
@Test
public void returnsPirateString() {
Pirate blackBeard = new Pirate();
Foo fooMock = mock(Foo.class);
fooMock.expectAndReturn("bar",1,"arrr!"); //expects 'bar' function to be called once and returns "arrr!"
assertEquals(blackBeard.yell(),"arrr!");
}
现在会发生什么,是如果我们重构方法栏来返回null而不是“arrr!”,我们的测试将继续愉快地运行,而我们的程序不能按照我们想要的方式工作。这可能会导致可能的调试噩梦。
使用mockist方法而不是单元测试的经典测试方法,大多数时候所有“helper”对象都会被嘲笑,只有被测试的对象才会被解除锁定,所以前面提到的问题也会经常发生。
可以做什么来防止这个问题,而嘲笑?
是的,但是这有点不利于嘲笑的使用,因为无论如何你必须创建你的数据结构来进行不同的测试。在这种情况下,我可以创建一个Object母体,并在这两个测试中使用这个母亲而不是嘲笑。 – tmetten 2010-09-30 14:45:02
我不确定我是否遵循...嘲讽的要点是单独测试您的不同类,以便您可以专注于测试受测试的特定类。在测试帮助者时,你应该测试那个帮助者与其他真正的类完全隔离。 – Pete 2010-09-30 15:06:18
是的,通过这样做,你的测试不会指出任何问题,而实际上课程会失败。 – tmetten 2010-09-30 15:17:10