프로그래밍/Spring
Spring Test @TestPropertySource Yml이 읽히지 않는다(?)
자바조아!
2024. 4. 9. 22:20
구조
TestServiceTest.java
package com.company.slot.oasis.api.slot.service;
import com.company.slot.oasis.api.config.TestConfig;
import com.company.slot.oasis.api.config.YamlPropertySourceFactory;
import com.company.slot.oasis.api.test.domain.TestService;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
@ExtendWith(SpringExtension.class)
//@TestPropertySource(locations = "classpath:application-test.yml")
//@TestPropertySource(properties = {"spring.config.location = classpath:application-test.yml"})
//@TestPropertySource(properties = {"classpath:/application-test.yml"})
//@TestPropertySource("classpath:application-test.yml")
@TestPropertySource(locations = "classpath:application-test.yml", factory = YamlPropertySourceFactory.class)
@ContextConfiguration(classes = TestConfig.class)
@EnableConfigurationProperties
class TestServiceTest {
@Autowired
private TestService testService;
@Test
@DisplayName("테스트 서비스에 Prop이 잘 주입되었는지 확인")
void createSlot() {
assertThat(testService.getValue()).isEqualTo("test");
}
}
application-test.yml
spring:
config:
activate:
on-profile: test
datasource:
url: jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;MODE=MySQL
driver-class-name: org.h2.Driver
username: sa
password:
jpa:
hibernate:
ddl-auto: update
properties:
hibernate:
dialect: org.hibernate.dialect.MySQL8Dialect
format_sql: true
globally_quoted_identifiers: true
show-sql: true
generate-ddl: true
database-platform: org.hibernate.dialect.MySQL8Dialect
database: h2
h2:
console:
enabled: true
test:
value: test
TestConfig.java
@Configuration
public class TestConfig {
@Autowired
private Environment env;
@Bean
public TestProp testProp() {
return new TestProp();
}
@Bean
public TestService testService() {
return new TestService(testProp());
}
}
TestServiceTest에서 @TestPropertySource을 이용해서 Property소스를 읽으려고 했습니다.
경로는 잘 찾더라구요.
문제는 아래와 같이 구성하면 구성하게 되면 .yml 형태로 읽는 것이아닌 .properties 형태로 읽게 됩니다.
@TestPropertySource(locations = "classpath:application-test.yml")
그래서 프로퍼티를 읽고나서 test.value 값이 존재 하지 않습니다.
test라는 값은 존재합니다.
value라는 값도 존재합니다.
즉 따로 국밥처럼 .yml이 아닌 .properties 형태로 읽힌것입니다.
많은 블로그들을 참조했더니 아래 처럼 하라고 하더군요
@TestPropertySource(properties = {"spring.config.location = classpath:application-test.yml"})
하지만 정상적으로 동작하지 않습니다.
key가 spring.config.location이고 value가 classpath:application-test.yml인 inline properties가 읽혀지더군요..
해결방안
그래서 해결 방안이 뭐냐?
간단합니다. 아래와 같이 yml을 읽을 때 팩토리를 등록해서 일도록해주면 됩니다.
그럼 test.value로 접근이 가능해 집니다.
@TestPropertySource(locations = "classpath:application-test.yml", factory = YamlPropertySourceFactory.class)
YamlPropertySourceFactory.java
public class YamlPropertySourceFactory implements PropertySourceFactory {
@Override
public PropertySource<?> createPropertySource(String name, EncodedResource encodedResource) throws IOException {
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResources(encodedResource.getResource());
return new PropertiesPropertySource(encodedResource.getResource().getFilename(), factory.getObject());
}
}