ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • TestCode 의 properties override 에 대하여
    Back-end 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 과 분리하고 싶은 경우 사용)

    반응형

    댓글

Designed by Tistory.