我在尝试测试类时遇到了一个问题,该类使用外部API -
JAMA软件
。假设有一个ClassA
。它有2种方法,我想使用Junit测试。两种方法都有ClassB
作为参数。
classB属于另一个API。我可以看到它的方法,但是实现详细信息不可用。(compiled code)
。问题是:如何模拟该类以使TestClass
隔离?我知道在Mockito
中有一个hardcode
响应的选项。是否有任何更好/清洁器这样做的方法,因此我不需要手动配置模拟对象?我将感谢有关该主题的任何建议。
从另一个答案中嘲笑的好阅读。
使用模拟方法与其方法的重点是将其与其依赖关系隔离。嘲笑的论点似乎很肮脏或不舒适,但旨在使您可以测试模拟班级的期望。在这种情况下,您假设无论您的服务班级是什么,都按预期工作(是否期望异常)。在这种情况下,我们正在测试A 单个单元 classa,并假设ClassB是正确的。
我将继续做一个更具体的例子,类似于上面的服务员/厨师示例。
假设您的班级是烹饪罐,而您的ClassB是餐具室。每当您与食品储藏室互动以Getpasta时,它都会尝试发送意大利面。如果没有意大利面,它将返回零。
食品储藏室是一个花哨的储藏室。它有一个存储内容的表,因此您不知道它是否具有面食。这在现实世界中是"复杂的",但这不是我们的储藏室。我们不知道它是如何工作的,只是它要么返回意大利面,要么不能返回意大利面。我们不知道逻辑,也不知道我们必须。我们知道它的作用,因此,如果我们要确保可以在锅中添加意大利面,我们可以使用以相同方式行事的模拟储藏室,而无需花哨的铃铛吹口哨。
食品储藏室还具有许多其他方法,例如允许您将剩余的意大利面添加到架子上。您不知道智能食品储藏室如何将面食重新放入,但是您不需要对其进行建模,因为无论如何,Mockito都可以使用Void Call。
。如果要更改ClassB,这些测试仍可能通过,但是您会在集成测试中遇到问题,并说:"嗯,我的班级仍然有效,但是新食品储藏室有些事情,所以我需要重做课程,并重新连接测试。"
CookingPot {
void addPasta(Pantry pantry) {
Pasta p = pantry.getPasta();
System.out.println("Added " + p.toString() + " to the pot!");
//fancy actions that use up some of the Pasta
pantry.add(p); //return the pasta
}
}
Pantry {
Pasta getPasta(); //we have no idea what this does in actuality
}
@Test(expected = NullPointerException.class)
public void testAddPastaButNoPastaLeft() {
Pantry mockPantry = mock(Pantry.class);
CookingPot cookingPot = new CookingPot();
cookingPot.addPasta(mockPantry);
//we should probably have checked if there was pasta before
//attempting to add imaginary pasta
}
@Test
public void testAddPasta() {
Pantry mockPantry = mock(Pantry.class);
when(mockPantry.getBaz()).thenReturn(new Pasta());
CookingPot cookingPot = new CookingPot();
cookingPot.addPasta(mockPantry);
}