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

SpringBoot 3.2.2集成测试中MockMvc与Mock仓库Bean为空求助

问题:SpringBoot 3.2.2集成测试中MockBean与MockMvc注入失败

核心问题

  • 标注@MockBean的DeliveryRepository、UserRepository始终为空
  • 疑惑为何必须手动模拟所有依赖Bean,是否存在自动模拟方式
  • 使用@WebMvcTest或@SpringBootTest+@AutoConfigureMockMvc时,@Autowired的MockMvc始终为空,不愿手动通过MockMvcBuilders初始化

已尝试操作

  • 移除@WebMvcTest(DeliveryController.class),改用以下注解组合:
@RunAs("SpringRunner.class")
@SpringBootTest
@AutoConfigureMockMvc
  • 拒绝使用手动初始化代码:
@BeforeEach
void setUp() {
    this.mockMvc = MockMvcBuilders.standaloneSetup(new DeliveryController(new DeliveryServiceImpl())).build();
}

当前测试类代码

@WebMvcTest(DeliveryController.class)
public class DeliveryControllerTest {

    @Autowired
    private static MockMvc mockMvc;

    @MockBean
    private DeliveryRepository deliveryRepository; // Mocking the repository

    @MockBean
    private UserRepository userRepository; // Mocking the repository

    @Test
    public void testCreateDelivery() throws Exception {
        DeliveryEntity delivery = DeliveryEntity.builder().deliveryId(1L).description("Test package").build();

        Mockito.when(deliveryRepository.save(Mockito.any(DeliveryEntity.class))).thenReturn(delivery);

        mockMvc.perform(get("/deliveries/1").contentType(MediaType.APPLICATION_JSON).content("{\"description\": \"Test package\"}"))
                .andExpect(status().isOk());

        Mockito.verify(deliveryRepository, Mockito.times(1)).save(Mockito.any(DeliveryEntity.class));
    }

    // Add more test methods for other endpoints
}

POM依赖配置

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>ch.qos.logback</groupId>
                    <artifactId>logback-classic</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>ch.qos.logback</groupId>
                    <artifactId>logback-classic</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.apache.logging.log4j</groupId>
                    <artifactId>log4j-to-slf4j</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-hateoas</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-rest</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>ch.qos.logback</groupId>
                    <artifactId>logback-classic</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.apache.logging.log4j</groupId>
                    <artifactId>log4j-to-slf4j</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <!--dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-docker-compose</artifactId> 
            <scope>runtime</scope> <optional>true</optional> </!dependency -->
        <dependency>
            <groupId>io.micrometer</groupId>
            <artifactId>micrometer-registry-prometheus</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>6.4.1.Final</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <scope>test</scope>
        </dependency>

</dependencies>

解决方案

1. 修复MockMvc注入失败

测试类中mockMvc被定义为static,Spring无法注入静态字段,直接移除static修饰符:

@Autowired
private MockMvc mockMvc; // 去掉static

2. 解决MockBean为空与依赖模拟问题

  • 为何需要手动Mock依赖:@WebMvcTest仅加载控制器相关Bean(控制器、转换器、过滤器等),不会加载Service、Repository等业务层Bean,因此必须用@MockBean模拟控制器依赖链中的所有Bean。
  • 自动模拟方式:可以使用@MockBean的批量模拟(比如直接Mock整个Service层),或结合@SpringBootTest+@MockBean(但会加载完整上下文,测试速度较慢);也可使用@SpyBean配合@Autowired,但仍需确保依赖链完整。
  • 注意Spring Boot 3.x默认使用JUnit 5,无需添加@RunWith(SpringRunner.class),@WebMvcTest已包含@ExtendWith(SpringExtension.class)。

3. 修正测试方法逻辑错误

测试中用get请求却传入JSON内容不符合规范,创建资源应使用post请求:

mockMvc.perform(post("/deliveries")
                .contentType(MediaType.APPLICATION_JSON)
                .content("{\"description\": \"Test package\"}"))
        .andExpect(status().isOk());

4. 消除依赖冲突

POM中手动指定的hibernate-core版本可能与Spring Boot 3.2.2默认版本冲突,建议移除该手动依赖,使用Spring Boot版本管理:

<!-- 移除以下手动指定的依赖 -->
<!--
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>6.4.1.Final</version>
</dependency>
-->

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 20:52:06