Mockito anyListOf:使用不同的实例作为参数覆盖结果

时间:2017-09-05 13:26:34

标签: java mockito

我正在尝试使用mockito根据列表元素的类型返回不同的结果。

假设我想在以下服务方法上获得不同的结果:

public class MyService {
   MyBean createBean(List<? extends A>, Report report) {
       //some super code
   } 
}

public interface A {

}

public class B implements A {

}

public class C implements A {

}

public Report {
    public List<B> bList;
    public List<C> cList;

    //getters and setters
}

方法createBean(..)在一个正在测试的类上,我想确保在调用时使用正确的列表调用它。所以我创建了以下模拟结果:

doReturn(createBean01()).when(myService).createBean(anyListOf(B.class), any(Report.class));
doReturn(createBean02()).when(myService).createBean(anyListOf(C.class), any(Report.class));

我期望在使用类型为B的元素的列表调用createBean方法时返回Bean01,而使用类型为C的元素的列表调用Bean02时返回Bean01。

我尝试了列表的特定实例,但行为是相同的。

doReturn(createBean01()).when(myService).createBean(report.getBList(),report);
doReturn(createBean02()).when(myService).createBean(report.getCList(),report);

看起来行为正在被覆盖。就像Mockito没有区分这些亚型。

什么让我失望?如何根据列表的类型使用不同的结果类型?

非常感谢。

1 个答案:

答案 0 :(得分:3)

你正在嘲笑错误。您可以使用模拟规范来表达/配置特定测试的特定设置。

我的意思是:除了在运行时擦除这样的事实,你(通常)不知道创建列表时使用的特定泛型类型 - 你真的不喜欢&#39;我希望您的测试代码对模拟对象的参数执行基于的操作。

换句话说:尽可能详细地记下您的测试,例如:

@Test
public void testWithA() {
  when(myService.createBean(someListOfBs)).thenReturn(someResultA);
  ...
}

@Test
public void testWithB() {
  when(myService.createBean(someListOfBs)).thenReturn(somethingElse);
  ...
}

含义:使用模拟规范 - 作为一个规范,告诉模拟框架它应该如何表现。避免开始围绕这些规范拥有复杂的逻辑!

并提示:你应该更喜欢当()。然后()而不是doAnswer()。when()。对于那些极少数情况,只有在选项1给出的更严格的类型检查时,才会使用后者...对于测试场景不起作用。