首页 > 解决方案 > 使用单元测试中的 @Service 实例调用方法时,@Repository 实例为空

问题描述

我的目标是为这些单元测试使用内存数据库,这些依赖项被列为:

implementation("org.springframework.boot:spring-boot-starter-data-jpa")
runtimeOnly("com.h2database:h2")

这样存储库实例实际上与数据库交互,我不只是模拟返回值。

问题是,当我运行单元测试时,服务实例中的存储库实例是null.

这是为什么?我是否缺少单元测试类上的一些注释来初始化存储库实例?

这是运行我的单元测试时的控制台输出:

null

java.lang.NullPointerException
    at com.my.MyService.findAll(MyService.java:20)
    at com.my.MyTest.testMy(MyTest.java:23)

我的单元测试类:

public class MyTest {

  @MockBean
  MyRepository myRepository;

  @Test
  void testMy() {
    MyService myService = new MyService();
    int size = myService.findAll().size();
    Assertions.assertEquals(0, size);
  }
}

我的服务等级:

@Service
public class MyService {

    @Autowired
    MyRepository myRepository;

    public List<MyEntity> findAll() {

        System.out.println(myRepository); // null
        return (List<MyEntity>) myRepository.findAll(); // throws NullPointerException
    }

    @Transactional
    public MyEntity create(MyEntity myEntity) {

        myRepository.save(myEntity);

        return myEntity;
    }
}

我的存储库类:

@Repository
public interface MyRepository extends CrudRepository<MyEntity, Long> {

}

我的实体类:

@Entity
public class MyEntity {

    @Id
    @GeneratedValue
    public Long id;
}

标签: javaspringspring-bootunit-testingjpa

解决方案


这是为什么?我是否缺少单元测试类上的一些注释来初始化存储库实例?

基本上是的:)

您需要通过注释您的 Testclass 来初始化 Spring Context@SpringBootTest

您遇到的另一个问题是您MyService手动创建对象。这样一来,SpringBoot 就没有机会为您注入任何 Bean。您可以通过简单地MyService在您的 Testclass 中注入您的来解决此问题。您的代码应如下所示:

@SpringBootTest
public class MyTest {

    @Autowired
    private MyService myService;

    @Test
    void testMy() {
        int size = myService.findAll().size();
        assertEquals(0, size);
    }
}

推荐阅读