【问题标题】:Testing library that is using spring boot 3使用 spring boot 3 的测试库
【发布时间】:2023-01-26 21:13:54
【问题描述】:

我有一个库,我想为存储库实施集成测试(仅作为更复杂案例的示例)。

为了重现该案例,我使用了this official example,但删除了AccessingDataJpaApplication.java 类,因为我会将其公开为库而不是应用程序。

现在 repo 没有 @SpringBootApplication 注释,the test 将失败,因为无法注入 private CustomerRepository customers;

如何重现案例:

git clone https://github.com/spring-guides/gs-accessing-data-jpa.git
cd gs-accessing-data-jpa/complete
mvn test # Working
rm src/main/java/com/example/accessingdatajpa/AccessingDataJpaApplication.java
mvn test # not working

问题是,如果它不是一个应用程序,那么注释这个测试的正确方法是什么?

我尝试用一​​些组合来注释测试,例如:

  • 添加@SpringBootTest
    @ExtendWith(SpringExtension.class)
    @DataJpaTest
    @SpringBootTest
    public class CustomerRepositoryTests {
    }
    
    该错误看起来像是试图说有多个初始化,我想每个注释都尝试自己做:
      [ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.067 s <<< FAILURE! - in com.example.accessingdatajpa.CustomerRepositoryTests
      [ERROR] com.example.accessingdatajpa.CustomerRepositoryTests  Time elapsed: 0.067 s  <<< ERROR!
      java.lang.IllegalStateException: Configuration error: found multiple declarations of @BootstrapWith for test class [com.example.accessingdatajpa.CustomerRepositoryTests]: [@org.springframework.test.context.BootstrapWith(value=org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTestContextBootstrapper.class), @org.springframework.test.context.BootstrapWith(value=org.springframework.boot.test.context.SpringBootTestContextBootstrapper.class)]
    
  • 仅设置@SpringBootTest
    @ExtendWith(SpringExtension.class)
    @SpringBootTest
    public class CustomerRepositoryTests {}
    
    然后我不能使用TestEntityManager并且仍然无法注入存储库
    17:29:01.951 [main] DEBUG org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Neither @ContextConfiguration nor @ContextHierarchy found for test class [CustomerRepositoryTests]: using SpringBootContextLoader
    17:29:01.954 [main] DEBUG org.springframework.test.context.support.AbstractContextLoader - Could not detect default resource locations for test class [com.example.accessingdatajpa.CustomerRepositoryTests]: no resource found for suffixes {-context.xml, Context.groovy}.
    17:29:01.954 [main] INFO org.springframework.test.context.support.AnnotationConfigContextLoaderUtils - Could not detect default configuration classes for test class [com.example.accessingdatajpa.CustomerRepositoryTests]: CustomerRepositoryTests does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
    17:29:01.964 [main] DEBUG org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Using ContextCustomizers for test class [CustomerRepositoryTests]: [ExcludeFilterContextCustomizer, DuplicateJsonObjectContextCustomizer, MockitoContextCustomizer, TestRestTemplateContextCustomizer, DisableObservabilityContextCustomizer, PropertyMappingContextCustomizer, Customizer]
    [ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.117 s <<< FAILURE! - in com.example.accessingdatajpa.CustomerRepositoryTests
    [ERROR] com.example.accessingdatajpa.CustomerRepositoryTests  Time elapsed: 0.116 s  <<< ERROR!
    java.lang.NullPointerException: Cannot invoke "java.lang.Class.getName()" because "found" is null
    
  • @SpringBootTest(classes = {CustomerRepository.class})
    @ExtendWith(SpringExtension.class)
    @SpringBootTest(classes = {CustomerRepository.class})
    public class CustomerRepositoryTests {}
    
    有错误:
    org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.example.accessingdatajpa.CustomerRepositoryTests': Unsatisfied dependency expressed through field 'customers': No qualifying bean of type 'com.example.accessingdatajpa.CustomerRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    

也许解决方案与[com.example.accessingdatajpa.CustomerRepositoryTests]: CustomerRepositoryTests does not declare any static, non-private, non-final, nested classes annotated with @Configuration.有关。但是具体怎么做呢?

顺便说一句:我在 Stackoverflow 中找到了this response,但它不起作用。也许是因为 Spring 版本。

【问题讨论】:

  • 第一个失败,因为您应该使用或@DataJpaTest(用于测试切片)或者@SpringBootTest 进行全面的集成测试。将两者都添加到测试用例中没有意义。您的测试失败,因为没有找到 @SpringBootConfiguration 类,因为您删除了应用程序。您现在基本上拥有一个没有 Spring Boot 功能的常规 Spring 应用程序。因此,您将需要通过提供配置来手动配置您的测试。
  • 感谢您的评论,但这正是我所解释的(我没有 SpringBootTest,因为它不是一个应用程序,第一个案例不起作用,因为我有多个初始化)。我的问题是关于如何测试它以及我需要哪组注释。我希望最后一个工作。
  • 为什么最后一个会起作用,因为它仍然是一个 @SpringBootTest,它找不到带有 @SpringBootApplication 的类来检查它以了解要实例化的内容。 (或者是 @SpringBootConfiguration),否则将不会自动配置。
  • 我可以在测试中的某个地方使用 @SpringBootConfiguration 来启用 Spring Boot 自动配置吗?

标签: java spring-boot spring-boot-test


【解决方案1】:

这是工作方法:

@ExtendWith(SpringExtension.class)
@DataJpaTest
public class CustomerRepositoryTests {

   @SpringBootApplication
   static class TestConfig {}

   @Autowired
   private TestEntityManager entityManager;

   @Autowired
   private CustomerRepository customers;

   @Test
   public void testFindByLastName() {
      ......

   }
}

所以每个测试类都会使用 Spring Boot 自动配置上下文。

参考:spring-data-examples repository

【讨论】:

    猜你喜欢
    • 2020-07-21
    • 2020-01-30
    • 2018-06-26
    • 1970-01-01
    • 2016-12-22
    • 1970-01-01
    • 2013-11-05
    • 2020-07-10
    • 2020-09-24
    相关资源
    最近更新 更多