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

SpringBoot中Mockito测试类出现NullPointerException问题求助

问题根源及解决步骤

1. JUnit版本注解冲突(MockMvc未初始化的直接原因)

测试类混用了JUnit 4的@Before和JUnit 5的@ExtendWith(MockitoExtension.class),JUnit 5不会执行JUnit 4的@Before方法,导致mockMvc始终为null。

修复方法:
将@Before替换为JUnit 5的@BeforeEach,导入对应包:

import org.junit.jupiter.api.BeforeEach;

// ...

@BeforeEach
public void setUp() throws Exception {
    MockitoAnnotations.openMocks(this);
    this.mockMvc = MockMvcBuilders.standaloneSetup(bookController).build();
}

同时删除测试类中多余的JUnit 4相关导入(如org.junit.runner.RunWith、org.mockito.junit.MockitoJUnitRunner),已使用JUnit 5的扩展注解,无需保留JUnit 4的运行器配置。

2. 依赖冗余与版本冲突

  • pom.xml中重复引入了两次junit依赖,删除其中一次;
  • spring-boot-starter-test已包含Mockito相关依赖,无需单独引入mockito-bom,删除该依赖避免版本冲突;

3. BookRepository的错误实现

手动实现JpaRepository的所有方法且多数返回null,会导致实际运行出错。Spring Data JPA仅需定义接口继承JpaRepository即可,无需手动实现:

@Repository
public interface BookRepository extends JpaRepository<Book, Long> {
    // 无需编写任何方法,Spring自动生成实现逻辑
}

4. 测试类导入错误

测试中is匹配器导入错误,应使用Hamcrest的匹配器而非ByteBuddy的:

import static org.hamcrest.Matchers.is;

修复后的完整BookControllerTest示例

package com.example.junitrestapiapplication;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;

import java.util.Arrays;
import java.util.List;

import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@ExtendWith(MockitoExtension.class)
public class BookControllerTest {
    private MockMvc mockMvc;
    ObjectMapper objectMapper = new ObjectMapper();
    ObjectWriter objectWriter = objectMapper.writer();

    @Mock
    private BookRepository bookRepository;

    @InjectMocks
    private BookController bookController;

    Book RECORD_1 = new Book(1L, "Atomic Habits", "How to build better habits", 5);
    Book RECORD_2 = new Book(2L, "Thinking Fast and Slow", "How to create good mental models about thinking", 4);
    Book RECORD_3 = new Book(3L, "Grokking Algorithms", "learn algorithms the fun way", 5);

    @BeforeEach
    public void setUp() throws Exception {
        this.mockMvc = MockMvcBuilders.standaloneSetup(bookController).build();
    }

    @Test
    public void getAllRecords_success() throws Exception {
        List<Book> records = Arrays.asList(RECORD_1, RECORD_2, RECORD_3);
        Mockito.when(bookRepository.findAll()).thenReturn(records);
        mockMvc.perform(MockMvcRequestBuilders
                        .get("/book")
                        .contentType(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$", hasSize(3)))
                .andExpect(jsonPath("$[2].name", is("Grokking Algorithms")));
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 05:24:58