【问题标题】:Junit 5 with test application.properties带有测试 application.properties 的 Junit 5
【发布时间】:2020-10-23 11:27:16
【问题描述】:

我正在学习 Junit 5 和测试用例。 我正在使用 Spring Boot 版本 '2.2.6.RELEASE 和 JUnit 5, 在我的应用程序中,我有一个基于属性文件中的布尔标志进行处理的方法。

\src\main\resources\application.properties

#data base connection properties
spring.app.datasource.url=jdbc:mysql://localhost:3306/student_db
spring.app.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.app.datasource.username=root
spring.datasource.password=root
spring.app.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect

#additional properties
spring.property.name=shrikant
spring.property.enable=false

数据库连接属性用于创建数据库连接

数据源.java

@Value("${spring.app.datasource.url}")
private String url;
@Value("${spring.app.datasource.driver-class-name}")
private String className;
@Value("${spring.app.datasource.username}")
private String userName;
@Value("${spring.datasource.password}")
private String password;
@Value("${spring.app.jpa.properties.hibernate.dialect}")
private String dialect;

控制器类

@RestController
public class Controller {
    @Value("${spring.property.name}")
    private String name;
    @Value("${spring.property.enable}")
    private boolean status;

    public void validateObject(String surName) {
        if (status) {                              # if this flag is true then only process
            System.out.println("name= " + name);
            System.out.println("surName= " + surName);
        }
    }

ControllerTest.java

@SpringBootTest
class ControllerTest {
    @Autowired
    private Controller controller;
    @Test
    void show() {
        controller.validateObject("sharma");
    }

默认情况下,该标志为 false,因此每次测试用例运行时它都不会处理对象。 所以我尝试在测试文件夹中创建 aplication.properties

\src\test\resources\application.properties

spring.property.name=vishal
spring.property.enable=true

但现在它给了我一个错误

Could not resolve placeholder 'spring.app.datasource.url'

但我不想提供数据库连接 URL,我在测试时没有连接到数据库。

Q1 - 如何仅为测试用例更改属性文件的值。

Q2 - 是否必须提供 \src\main\resources\application.properties 为 \src\test\resources\application.properties 的所有键?

我是测试用例的新手,所以欢迎很少解释的答案。

更新:- 我发现了

@SpringBootTest
@TestPropertySource(properties = {"spring.property.name=vishal", " spring.property.status=true"})
class ControllerTest {

将通过提供键值和值来暂时解决问题,但是我有很多键,无法以这种方式提供。

【问题讨论】:

    标签: java unit-testing junit junit5


    【解决方案1】:

    如果您使用@SpringBootTest,那么您的测试将加载整个 Spring 上下文。这意味着它将创建您所有的 bean 并尝试将它们连接在一起。如果将属性值注入 bean,则必须为此类测试指定它们all,否则将无法启动应用程序。

    在这种情况下可能对您有所帮助的是使用 @WebMvcTest@DataJpaTest 等测试注释来专注于测试应用程序的片段。使用@WebMvcTest,您将获得一个应用程序上下文,其中仅包含控制器以及与您的 Web 层相关的所有内容。可以使用@MockedBean 模拟其他 bean(如服务类)。

    接下来,为了测试服务类中的业务逻辑,尽量不要使用@SpringBootTest,而是依靠普通的 JUnit 5 和 Mockito 来验证您的代码。

    您仍然可能希望进行一些使用@SpringBootTest 的集成测试,以确保一切正常工作。在这种情况下,您可以在src/test/resources/ 中对application.properties 内的任何静态属性进行硬编码,或者使用您已经做过的注释:@TestPropertySource(properties = {"spring.property.name=vishal", " spring.property.status=true"})

    在提供数据库时,您可以配置嵌入式数据库(我会尽量避免)或使用与生产环境相同的数据库。 Testcontainers 在为您的测试提供外部基础架构(如数据库)方面为您提供了很多帮助。

    使用 Spring Boot >= 2.2.6 和 JUnit 的示例设置可能如下所示:

    @Testcontainers
    @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
    public class ApplicationIT {
     
      @Container
      public static PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer()
        .withPassword("password")
        .withUsername("username");
     
      @DynamicPropertySource
      static void postgresqlProperties(DynamicPropertyRegistry registry) {
        registry.add("spring.datasource.url", postgreSQLContainer::getJdbcUrl);
        registry.add("spring.datasource.password", postgreSQLContainer::getPassword);
        registry.add("spring.datasource.username", postgreSQLContainer::getUsername);
      }
     
      @Test
      public void contextLoads() {
      }
     
    }
    

    【讨论】:

      【解决方案2】:

      对于 Junit5,在您的 src/main/resources 中使用 application.properties 的路径注释您的测试类:

      @ExtendWith(SpringExtension.class)
      @TestPropertySource("classpath:application.properties")
      public class MyTest {
          @Value("${property.name}")
          private int myProperty;
          tests...
      }
      

      属性被加载

      【讨论】:

        猜你喜欢
        • 2020-04-07
        • 1970-01-01
        • 2015-07-21
        • 2019-08-23
        • 2014-03-09
        • 2022-08-20
        • 2020-03-20
        • 1970-01-01
        • 2019-04-25
        相关资源
        最近更新 更多