Back-end

TestCode 의 properties override 에 대하여

HOONY_612 2024. 3. 8. 16:07
반응형

개요

TestCode 의 properties 파일에 대한 오해가 있어서 간단히 정리해보려 한다.

스프링에 대한 실력이 부족해서 업무 중 실수를 했다 ㅠ

다음엔 실수하지 않도록 정리를 해놓자. 

 

내가 하려고 했던 방향

기존의 propeties 파일 및 통합 테스트 어노테이션이다.

@ActiveProfiles("test")
@AutoConfigureTestDatabase
@ExtendWith(SpringExtension.class)
@SpringBootTest
public abstract class NdapSpringIntegrationTestBase {
}

 

test/application.properties 를 만들지 않고 test/application-test.properties + @ActiveProfiles 를 조합하여 사용하지?

그래 test/application.properties 를 만들고 @ActiveProfiles 는 제거해버리자!!( 실수 )

아래는 PR 에서 받았던 리뷰이다. 

 

음.. 나의 생각은 왜 main/resources/application.properties 를 test package 에서 사용하는 거지..? 라는 의문이 생겼다.

그리고 고정관념? 비슷해서 @SpringBootTest 실행하면 무조건 test/resouces 에 있는 properties 파일을 읽는다고 생각했고 없으면 에러가 나는 줄 알았다... ( 두 번째 실수 )

그러나 없을 시 main/resources/application.properties 파일을 사용했다.

이러한 상황에서 properties 관련한 테스트가 필요했다.

 

Test 위한 기본 Setting

아래의 2가지 파일을 추가하자.

@Component
public class PropertySourceResolver {

    @Value("${example.firstProperty}") private String firstProperty;
    @Value("${example.secondProperty}") private String secondProperty;

    public String getFirstProperty() {
        return firstProperty;
    }

    public String getSecondProperty() {
        return secondProperty;
    }
}

 

<main/resources/application.properties>

example.firstProperty=defaultFirst
example.secondProperty=defaultSecond

 

그리고 테스트 코드를 작성한다. (test/resouces/application.properties 없는 상태)

main/resources/application.properties 를 읽어온다.

@SpringBootTest
public class TestResourcePropertySourceResolverIntegrationTest {

    @Autowired
    private PropertySourceResolver propertySourceResolver;

    @Test
    public void shouldTestResourceFile_overridePropertyValues() {
        String firstProperty = propertySourceResolver.getFirstProperty();
        String secondProperty = propertySourceResolver.getSecondProperty();

        assertEquals("defaultFirst", firstProperty);
        assertEquals("defaultSecond", secondProperty);
    }
}

 

Test 1. test/resources/application.properties 추가

아래 파일을 추가하자. 그럼 어떻게 될까?

 

<test/resources/application.properties>

example.firstProperty=file
example.secondProperty=file

 

테스트 코드는 통과한다.

String firstProperty = propertySourceResolver.getFirstProperty();
String secondProperty = propertySourceResolver.getSecondProperty();

assertEquals("file", firstProperty);
assertEquals("file", secondProperty);

 

그럼 test/resources/application.properties 에서 하나의 속성을 지워보자.

example.firstProperty=file

 

main/resources/application.properties 값을 못 읽어오면서 에러가 발생한다.

Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'example.secondProperty' in value "${example.secondProperty}"

 

따라서 test/resources/application.properties 가 존재하면 main/resources/application.properties 를 사용할 수 없다는 얘기가 된다.

 

Test 2. test/resources/application-test.properties + @ActiveProfile 추가

 

그럼 위 상황(main/resources/application.properties, test/resources/application.properties 에 properties 파일이 모두 있는 경우)에서 아래 파일을 추가해보자.

 

<test/resources/application-test.properties>

example.firstProperty=profile

 

@ActiveProfiles 를 붙여서 테스트 코드를 작성하자.

@ActiveProfiles("test")
@SpringBootTest
public class TestResourcePropertySourceResolverIntegrationTest {

    @Autowired
    private PropertySourceResolver propertySourceResolver;

    @Test
    public void shouldTestResourceFile_overridePropertyValues() {
        String firstProperty = propertySourceResolver.getFirstProperty();
        String secondProperty = propertySourceResolver.getSecondProperty();

        assertEquals("profile", firstProperty);
        assertEquals("file", secondProperty);
    }
}

 

결과적으로 firstPropertytest/resources/application-test.properties, secondePropertytest/resources/application.properties 에서 읽어 온다.

 

만약 test/resources/application.properties 가 없다면? 난 에러를 예상했다. 그러나...

firstPropertytest/resources/application-test.properties, secondePropertymain/resources/application.properties 에서 읽어왔다.. 즉 기본 파일에 test 파일이 override 되는 형태였다.

 

결론

두 방법은 비슷해보이지만 목적 자체가 다르다.

 

1. @ActiveProfiles("test") + test/resources/application-test.properties

      - main/resources/application.properties override 하기 위한 목적(필요한 변수만 변경해서 테스트하는 경우 사용) 

2. @ActiveProfiles("test") 제거 +  test/resources/application.properties

      - main/resources/appliaction.properties 와는 별개로 동작(properties 를 main 과 분리하고 싶은 경우 사용)

반응형