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

已添加注解但@Autowired注入的movieRepository仍为空问题排查

问题:Spring Boot集成测试中@Autowired注入MongoRepository出现NullPointerException

问题描述

编写MongoDB集成测试时,@Autowired注入的MovieRepository字段抛出NullPointerException。已知MongoRepository无需添加@Repository注解(添加后问题未解决),测试类继承的抽象类已标注@DataMongoTest,但问题依然存在。

代码与环境信息

环境

  • Java 17
  • Spring Boot 3.0 RC1
  • JUnit 5
  • Maven
  • 依赖:Spring Web、Spring Data MongoDB、Lombok、Testcontainers

相关代码

MovieRepository.java(/main/目录)

package com.example.testingtwo.repository;
public interface MovieRepository extends MongoRepository<Movie, String> {

}

AbstractContainerBaseTest.java(/test/目录)

package com.example.testingtwo;
@DataMongoTest
public abstract class AbstractContainerBaseTest {

    static final MongoDBContainer mongoDBContainer;

    static {
        mongoDBContainer = new MongoDBContainer(DockerImageName.parse("mongo:6.0.2"));
        mongoDBContainer.start();
    }

    @DynamicPropertySource
    static void setProperties(DynamicPropertyRegistry registry) {
        registry.add("spring.data.mongodb.uri", mongoDBContainer::getReplicaSetUrl);
    }
}

MovieRepositoryIntegrationTest.java(/test/目录)

package com.example.testingtwo.repository;
public class MovieRepositoryIntegrationTest extends AbstractContainerBaseTest {

    @Autowired
    private MovieRepository movieRepository;

    @AfterEach
    void cleanUp() {
        movieRepository.deleteAll();
    }

    @Test
    public void testFindById() {
        Movie movie = new Movie(null, "Test Name", "Test Description");
        String movieId = movieRepository.save(movie).getId(); // 抛出NullPointerException: this.movieRepository is null
        Movie movieFound = movieRepository.findById(movieId).orElse(null);

        assertNotNull(movieFound);
        assertEquals(movieFound.getName(), movie.getName());
        assertEquals(movieFound.getDescription(), movie.getDescription());
    }
}

解决方案

问题出在测试子类MovieRepositoryIntegrationTest未被Spring Boot测试上下文正确加载。虽然抽象类标注了@DataMongoTest,但该注解不会自动让子类被Spring测试框架识别并初始化上下文。

修复步骤

在MovieRepositoryIntegrationTest类上添加@DataMongoTest注解,确保Spring Boot测试框架启动MongoDB切片测试上下文,完成依赖注入:

package com.example.testingtwo.repository;
@DataMongoTest // 添加该注解
public class MovieRepositoryIntegrationTest extends AbstractContainerBaseTest {

    @Autowired
    private MovieRepository movieRepository;

    // 其余代码不变
}

可选优化

如果希望抽象类仅负责Testcontainers配置,可将@DataMongoTest移到子类,移除抽象类上的该注解,结构更清晰:
修改后的AbstractContainerBaseTest.java

package com.example.testingtwo;
// 移除@DataMongoTest
public abstract class AbstractContainerBaseTest {

    static final MongoDBContainer mongoDBContainer;

    static {
        mongoDBContainer = new MongoDBContainer(DockerImageName.parse("mongo:6.0.2"));
        mongoDBContainer.start();
    }

    @DynamicPropertySource
    static void setProperties(DynamicPropertyRegistry registry) {
        registry.add("spring.data.mongodb.uri", mongoDBContainer::getReplicaSetUrl);
    }
}

修改后的MovieRepositoryIntegrationTest.java

package com.example.testingtwo.repository;
@DataMongoTest
public class MovieRepositoryIntegrationTest extends AbstractContainerBaseTest {
    // 其余代码不变
}

原理说明

@DataMongoTest是Spring Boot提供的切片测试注解,用于启动仅包含MongoDB相关组件的测试上下文。只有当测试类直接标注该注解时,Spring才会初始化上下文并完成依赖注入,抽象类的注解不会自动传递给子类生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 10:15:34