从单元测试中使用 @Service 实例调用方法时,@Repository 实例为 null

bob*_*e01 1 java spring unit-testing jpa spring-boot

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

implementation("org.springframework.boot:spring-boot-starter-data-jpa")
runtimeOnly("com.h2database:h2")
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

null

java.lang.NullPointerException
    at com.my.MyService.findAll(MyService.java:20)
    at com.my.MyTest.testMy(MyTest.java:23)
Run Code Online (Sandbox Code Playgroud)

我的单元测试课:

public class MyTest {

  @MockBean
  MyRepository myRepository;

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

我的服务等级:

@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;
    }
}
Run Code Online (Sandbox Code Playgroud)

我的存储库类:

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

}
Run Code Online (Sandbox Code Playgroud)

我的实体类:

@Entity
public class MyEntity {

    @Id
    @GeneratedValue
    public Long id;
}
Run Code Online (Sandbox Code Playgroud)

Jan*_*itz 5

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

基本上是的:)

您需要通过注释您的测试类来初始化 Spring 上下文@SpringBootTest

您遇到的另一个问题是您MyService手动创建对象。这样SpringBoot就没有机会为你注入任何Bean。您可以通过简单地将您的代码注入MyService到您的测试类中来解决此问题。你的代码应该是这样的:

@SpringBootTest
public class MyTest {

    @Autowired
    private MyService myService;

    @Test
    void testMy() {
        int size = myService.findAll().size();
        assertEquals(0, size);
    }
}
Run Code Online (Sandbox Code Playgroud)