You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 21:16:07