Junit 5 with test application.properties



我正在学习Junit 5和测试用例。 我正在使用 Spring 启动版本'2.2.6.发布和 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);
}
}

控制器测试.java

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

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

\src\test\resources\application.properties

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

但现在它给了我一个错误

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

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

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

问题 2 - 是否必须提供 \src\main\resources\application.properties

的所有键是 \src\test\resources\application.properties?

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

更新:- 我发现

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

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

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

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

接下来,为了在服务类中测试业务逻辑,尽量不要使用@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() {
}

}

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

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

属性已加载

最新更新