본문 바로가기
프로젝트/개인 프로젝트) 요만큼

Docker ) MySQL 컨테이너를 사용하는 서비스를 테스트하자 !

by 휴일이 2023. 11. 2.

 

 

테스트 코드를 작성해야하는데

도커 컨테이너를 사용해서 MySQL 을 사용하기 때문에

약간 추가 설정이 더 필요하다.

 

직접 @Containers 애노테이션 등을 이용해 컨테이너를 직접 설정해 사용하는 법도 있으나

나는 간단한 방법을 이용했다.

 

 

 

일단 이 방법은

Proxy 컨테이너를 만들어서 사용하는 게 아니라

직접 만든 컨테이너를 그대로 사용할 건데, 얘네가 그 컨테이너가 뭔지 알 수 있게 설정을 잡아주는 과정이라고 보면 된다.

얘네는 우리가 만든 컨테이너를 그대로 사용할 거다. 새로 만드는 게 아니라..

 

 

 

처음엔 src/test/resources/application.yml 에...

spring:
  datasource:
    driver-class-name: org.testcontainers.jdbc.ContainerDatabaseDriver
    url: jdbc:tc:mysql:latest:///
    username: yomankum
    password: 비번

 

요 내용을 작성해준다.

url 부분이 중요한데,

tc <- 이 부분을 넣어주면 호스트명, DB 명을 적지 않아도 application.yml 이 자동으로 컨테이너를 잡아준다 @.@

username, password 는 내 mysql 컨테이너와 동일하게 잡아준다.

 

 

 

Test

@Transactional
@ActiveProfiles("test")
@SpringBootTest
class SignUpServiceImplTest {

    @Autowired
    private UserRepository userRepository;
    @Autowired
    private SignUpService signUpService;
    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    @BeforeEach
    void clean() {
        userRepository.deleteAll();
    }

    @Test
    @DisplayName("성공 : 회원가입 성공")
    void 회원가입_성공() throws Exception {

        UserSignUpDto userSignUpDto = getUserSignUpDto();

        signUpService.signUp(userSignUpDto);

        User findUser = userRepository.findByUsername(userSignUpDto.getUsername()).orElse(null);

        boolean pwdMatches = passwordEncoder.matches(userSignUpDto.getPassword(), findUser.getPassword());

        assertThat(findUser).isNotNull();
        assertThat(findUser.getUsername()).isEqualTo(userSignUpDto.getUsername());
        assertThat(pwdMatches).isTrue();
    }

    @Test
    @DisplayName("실패 : 중복 회원")
    void 회원가입_실패_중복회원() throws Exception {


        UserSignUpDto userSignUpDtoA = getUserSignUpDto();
        UserSignUpDto userSignUpDtoB = getUserSignUpDto();

        signUpService.signUp(userSignUpDtoA);
        assertThrows(UserDuplicateException.class, () -> signUpService.signUp(userSignUpDtoB));

    }

    UserSignUpDto getUserSignUpDto() {
        return UserSignUpDto.builder()
                .username("username")
                .password("password")
                .build();
    }
}

 

 

테스트 코드를 작성했는데 특이한 점을 보시라.

 

@Transactional
@ActiveProfiles("test")
@SpringBootTest
class SignUpServiceImplTest {

 

@ActiveProfiles("test") 애노테이션이 보인다.

 

스프링 도큐먼트를 들어가보자 !

테스트 클래스를 로드 할 때 사용하는 활성 Bean 의 정의 Profile 을 선언하는 클래스 수준 주석이다.

한 마디로 얘를 붙여주면 테스트 클래스를 로드할 때 설정 파일을 가져다주는 것인데.

resources/application.yml 은 기본적으로 autoconfiguration 해준다.

 

게다가 3번째 줄에 보면 이 주석은 기본적으로 포함된 테스트 클래스에서 상속된다고 나온다.

그러니까 이 애노테이션을 지워도 돌아간다는 것.

 

그러면 다시!

 

 

사실은 해당 애노테이션을 삭제해도 돌아가는 것이다.

 

 

결론은 -> 다 필요 없고 그냥 application.yml 만 적어주면 컨테이너 사용 가능!!

 

 

 

이렇게 잘 돌아가는 모습을 확인할 수 있다 ^^7

 

 

 

 

그리고 Mac을 사용하며 테스트에서만 도커를 잡지 못해 난항을 겪었는데

혹시 맥을 사용하는데 터미널이나 서버 빌드할 때는 도커를 잘 잡는데

테스트에서만 도커를 찾을 수 없다고 뜨면

아래 링크를 들어가서 해결 방법을 확인해보세요 !!

https://hyuil.tistory.com/263

 

Docker ) Could not find a valid Docker environment. Please see logs and check configuration

Mac M2로 도커 테스트를 시도하던 나. 문제가 발생했다. 이렇게 도커 설정을 찾을 수 없다고 나온다. 한 마디로 연결이 안 되는 것. 나는 @ActiveProfiles 로 test/resources/application.yml 설정을 직접 사용중

hyuil.tistory.com

 

 

728x90