본문 바로가기

공부/TIL

23.12.01

테스트 코드 작성중 생겼던 의문들을 정리해보자.

 

1. 테스트시 인자에 객체를 넘겨줄 때 생기는 오류는 어떻게 대처해야 하는가?

 (Strict stubbing argument mismatch. Please check) 에러

given(menuRepository.save(menu)).willReturn(resultMenu);
// save(menu)는 오류가 난다.

 

Repository에 save메서드에 Menu 객체를 넣으면 생기는 오류. 이것외에 테스트 코드를 작성하며 인자에 객체를 넣을 때마다 오류가 발생했다. NPE가 떴었다. 해당 지점은 항상 객체를 생성해주는 코드였다. 이 오류가 나는 이유는 다음과 같다.

MenuService의 post 메서드는 이렇게 구현되어있다.

public MenuResponseDto post(MenuRequestDto menuRequestDto, UserDetailsImpl userDetails) {
        user = userDetails.getUser();
        // 여기서 new Menu(menuRequestDto);로 생성된 menu가 test단의 menu와 같지 않다.
        menu = new Menu(menuRequestDto);
        menu.setUser(user);
        // 회원 인증 기능 추가
        menu = menuRepository.save(menu);
        return new MenuResponseDto(menu);
    }

이때 생성된 menu와 테스트에서 생성된 menu는 다른 객체다. 서로 다른 new를 통해 생성됐기 때문에. 따라서

given(menuRepository.save(any())).willReturn(resultMenu);
// save(any())는 정상적으로 테스트를 통과.

객체를 인자에 넣어서 테스트 할 때는 any()를 사용해서 하는 게 좋다. 왜냐하면 우리는Repository의 save를 테스트 하는것이 아니다. reeturn값은 우리가 이미 만들어서 정해 놓기 때문에 return값이 이건데, when파트에서 실행된 테스트가 내가 예상하는 결과값과 일치하는지를 확인하면 된다. 

 

2. 실제 개발 환경에서 사용될 DB와 테스트용 DB는 분리 되어야 한다.

테스트를 하기 위해 사용해야 할 DB는 분리 되어야 한다. 왜냐하면 실제 서비스에서 사용해야 할 DB를 테스트에서도 공유하면 테스트정보가 저장이 되면 안되기 때문. 또 내 뇌피셜이지만, 실제 DB는 로딩하는데 시간이 좀 오래 걸리지 않을까? 그렇담 TEST원칙의 FIRST의 fast를 위반하지 않을까? 라고 생각했다.

그렇다면 어떻게 TEST용 DB를 관리 하는가?

1) 테스트용 application.properties를 추가한다. application-test.properties를 하나 더 추가해준다.

spring.config.activate.on-profile=test
spring.datasource.url=jdbc:h2:mem:testdb;MODE=MySQL

그리고 첫번째줄을 써주면 test용으로 쓰겠다고 선언 한 것. 우리는 h2 DB를 사용할 것이지만? MySQL문법을 사용하기 위해서 MODE=MySQL을 써준다. 이렇게 하면 h2 DB를 Test용으로 하나 생성한 것. 그리고 이 DB를 사용하기 위해서는 Test할 때

@ActiveProfiles("test")

어노테이션을 하나 달아주면 된다. 이렇게 하면 test로 선언된 DB를 사용하게 된다. 그리고 기존에 사용하던 DB에는

spring.config.activate.on-profile= dev

설정을 하나 추가 해주면 된다.

'공부 > TIL' 카테고리의 다른 글

23.12.05  (2) 2023.12.05
23.12.04  (0) 2023.12.04
23.11.30  (0) 2023.11.30
23.11.29  (0) 2023.11.29
23.11.28  (0) 2023.11.28