java - stub 方法时出现 InvalidUseOfMatchersException

标签 java tdd testng mockito

我有这个 TestNG 测试方法代码:

@InjectMocks
private FilmeService filmeService = new FilmeServiceImpl();

@Mock
private FilmeDAO filmeDao;

@BeforeMethod(alwaysRun=true)
public void injectDao() {
    MockitoAnnotations.initMocks(this);
}

//... another tests here

@Test
public void getRandomEnqueteFilmes() {
    @SuppressWarnings("unchecked")
    List<Filme> listaFilmes = mock(List.class);

    when(listaFilmes.get(anyInt())).thenReturn(any(Filme.class));
    when(filmeDao.listAll()).thenReturn(listaFilmes);

    List<Filme> filmes = filmeService.getRandomEnqueteFilmes();

    assertNotNull(filmes, "Lista de filmes retornou vazia");
    assertEquals(filmes.size(), 2, "Lista não retornou com 2 filmes");
}

我收到了“org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 参数匹配器的使用无效! 预期 0 个匹配器,记录 1 个:”在此代码中调用 listAll() 方法时:

@Override
public List<Filme> getRandomEnqueteFilmes() {
    int indice1, indice2 = 0;
    List<Filme> filmesExibir = new ArrayList<Filme>();
    List<Filme> filmes = dao.listAll();

    Random randomGenerator = new Random();
    indice1 = randomGenerator.nextInt(5);
    do {
        indice2 = randomGenerator.nextInt(5);
    } while(indice1 == indice2);

    filmesExibir.add(filmes.get(indice1));
    filmesExibir.add(filmes.get(indice2));

    return filmesExibir;
}

我很确定我在这里遗漏了一些东西,但我不知道它是什么!有人帮忙吗?

最佳答案

when(listaFilmes.get(anyInt())).thenReturn(any(Filme.class));

这就是你的问题。您不能在返回值中使用anyany 是一个匹配器,它用于匹配参数值以进行 stub 和验证,并且在定义调用的返回值时没有意义。您需要显式返回一个 Filme 实例,或将其保留为空(这是默认行为,这会破坏 stub 点)。

我应该注意到,使用真实列表而不是模拟列表通常是一个好主意。与您开发的自定义代码不同,列表实现是定义良好且经过良好测试的,并且与模拟列表不同,如果您重构被测系统以调用不同的方法,则真正的列表不太可能损坏。这是风格和测试理念的问题,但您可能会发现在这里使用真实的列表是有利的。

<小时/>

为什么上述规则会导致该异常?好吧,这个解释打破了 Mockito 的一些抽象概念,但是 matchers don't behave like you think they might — 它们将一个值记录到 ArgumentMatcher 对象的 secret ThreadLocal 堆栈上,并返回 null 或其他虚拟值,并在调用 whenverify 时> Mockito 看到一个非空堆栈,并且知道优先使用这些匹配器而不是实际参数值。就 Mockito 和 Java 评估顺序而言,您的代码如下所示:

when(listaFilmes.get(anyInt())).thenReturn(null);
when(filmeDao.listAll(any())).thenReturn(listaFilmes); // nonsense

自然地,Mockito 会看到一个 any 匹配器,而 listAll 不接受参数,因此预期有 0​​ 个匹配器,记录了 1 个

关于java - stub 方法时出现 InvalidUseOfMatchersException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21738336/

相关文章:

testing - 使用 arquillian incontainer 模式,为什么测试方法在 testng 中被数据提供者返回值的时间平方?

java - 如何更改 DataInputStream 的内部缓冲区大小

c# - Membership.CreateUser 的 ASP.NET MVC 3 单元测试总是返回 MembershipCreateStatus 错误

java - 在一个testng xml中包含多个testng xml

javascript - 如何在YUI3中使用Assert.isUndefine()和Assert.isNotUndefine()?

tdd - 如何为技术实现细节编写用户故事?

java - 无法在 testng 套件中的 <test> 标签之间传递数据

java - 如何 "scan"获取信息的网站(或页面),并将其带入我的程序?

java - 防止升级时 sqlite 数据库丢失数据

java - 使用自定义分隔符列解析 CSV 未正确映射到 POJO