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

Mockito的thenReturn()方法返回null值问题求助

刚接触Mockito遇到这种thenReturn返回null的问题太正常了,我结合你用@WebMvcTest的场景,给你梳理几个最可能的原因和解决办法:

1. 先检查setUp里的mock初始化是否完整

首先你得确认两件事:

  • 你有没有给moviesMock填充实际的Movie对象?如果只是new ArrayList<>()但没加元素,虽然不会返回null,但接口返回空列表;但如果连moviesMock本身都没初始化(比如忘了moviesMock = new ArrayList<>()),那thenReturn传的就是null,自然返回null。
  • 你mock的方法签名和Controller里调用的完全匹配吗?比如Controller调用的是movieService.getMoviesByYear(2023),但你mock的是movieService.getAllMovies(),这种不匹配的情况,Mockito会返回默认值null。

正确的初始化示例:

@Before
public void setUp() {
    // 先初始化mock列表并添加数据
    moviesMock = new ArrayList<>();
    moviesMock.add(new Movie(1L, "星际穿越", "科幻"));
    moviesMock.add(new Movie(2L, "肖申克的救赎", "剧情"));
    
    // 确保mock的方法和Controller调用的完全一致
    when(movieService.getAllMovies()).thenReturn(moviesMock);
}

2. 确认@MockBean的使用逻辑

在@WebMvcTest中,@MockBean会自动替换Spring容器里的MovieService实例,所以要确保你的Controller是通过@Autowired注入MovieService的,而不是手动new了一个实例——如果Controller里自己new MovieService(),那它根本不会用到你mock的这个实例,自然返回null。

3. 检查Mockito静态方法的导入和使用

有没有不小心导入错了when方法?必须是org.mockito.Mockito.when,如果导入了其他包的同名方法,mock逻辑根本不会生效。

另外,你可以试试用doReturn替代thenReturn,这种写法在某些场景下(比如mock已经被调用过的方法)更可靠:

doReturn(moviesMock).when(movieService).getAllMovies();

4. 快速调试技巧

在测试方法里先直接调用mock的方法,看看返回值:

@Test
public void testMock() {
    List<Movie> testResult = movieService.getAllMovies();
    // 如果这里是null,说明mock设置有问题;如果正常,再排查MockMvc的请求映射
    System.out.println(testResult);
}

完整的测试示例参考

@RunWith(MockitoJUnitRunner.class)
@WebMvcTest(value = MovieRestApiController.class, secure = false)
public class MovieRestApiControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private MovieService movieService;

    private ArrayList<Movie> moviesMock;

    @Before
    public void setUp() {
        // 初始化测试数据
        moviesMock = new ArrayList<>();
        moviesMock.add(new Movie(1L, "Inception", "Sci-Fi"));
        moviesMock.add(new Movie(2L, "The Shawshank Redemption", "Drama"));

        // 设置mock返回值
        when(movieService.getAllMovies()).thenReturn(moviesMock);
    }

    @Test
    public void testGetAllMoviesSuccess() throws Exception {
        // 先验证mock是否生效
        Assert.assertEquals(2, movieService.getAllMovies().size());

        // 再测试接口
        mockMvc.perform(get("/api/movies")
                .contentType(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$", hasSize(2)))
                .andExpect(jsonPath("$[0].title", is("Inception")));
    }
}

最后再提醒一句:一定要仔细核对Controller里调用的MovieService方法名、参数类型和数量,和你mock的完全一致,这是最容易踩的坑!

内容的提问来源于stack exchange,提问作者senham

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 11:05:14