JUnit5/Mockito单元测试返回错误值:查询结果不符预期求助
单元测试按作者查询返回全部数据的修复方案
问题原因
你当前的Mockito mock设置用了any()作为参数匹配器,这意味着不管传入任何作者参数,Repository都会返回包含两本书的完整列表,完全跳过了实际的参数过滤逻辑,所以测试永远返回2条数据,和预期的1条不符。
修复方案
方案1:针对具体参数返回对应结果
直接匹配测试中用到的参数,返回预先过滤好的列表:
@Test public void findByAuthors(){ List<Book> books = getBooks(); // 匹配"testAuthor2"参数,返回仅包含对应作者的书籍 Mockito.when(bookRepository.findByAuthorContainingIgnoreCase("testAuthor2")) .thenReturn(books.stream() .filter(book -> "testAuthor2".equals(book.getAuthor())) .toList()); List<Book> result = bookService.findByAuthorContaining("testAuthor2"); Assertions.assertEquals(1, result.size()); }
方案2:动态处理参数(贴近真实业务逻辑)
用Answer接口模拟真实的ContainingIgnoreCase模糊匹配逻辑,自动过滤符合条件的书籍,适合覆盖更多测试场景:
@Test public void findByAuthors(){ List<Book> books = getBooks(); Mockito.when(bookRepository.findByAuthorContainingIgnoreCase(anyString())) .thenAnswer(invocation -> { // 获取传入的作者参数 String inputAuthor = invocation.getArgument(0); // 模拟忽略大小写的包含匹配逻辑 return books.stream() .filter(book -> book.getAuthor() .toLowerCase() .contains(inputAuthor.toLowerCase())) .toList(); }); List<Book> result = bookService.findByAuthorContaining("testAuthor2"); Assertions.assertEquals(1, result.size()); // 额外测试忽略大小写的场景 List<Book> caseInsensitiveResult = bookService.findByAuthorContaining("TESTAUTHOR"); Assertions.assertEquals(1, caseInsensitiveResult.size()); }
说明
方案1适合单一参数的简单测试,方案2更贴近实际业务的模糊查询逻辑,能同时覆盖大小写忽略、部分匹配等场景,推荐用方案2来让单元测试更接近真实运行的逻辑。
内容的提问来源于stack exchange,提问作者Viktar Nikanenka
相关产品推荐
相关产品推荐

