Dev_Henry

[Spring] mock을 이용한 mvc 단위테스트 - 1. repository 본문

Web/Spring

[Spring] mock을 이용한 mvc 단위테스트 - 1. repository

데브헨리 2023. 7. 25. 00:09
728x90

 

스프링부트를 이용하여 프로젝트를 하던중 1차 개발이 끝나고 2차 개발을 시작하기 전에 컨벤션에 맞지 않는 무분별한 네이밍과 깔금하지 못한 코드들을 리팩토링하는 과정을 먼저 거쳤다.

팀원 모두 스프링에 대한 이해도가 부족한 상태에서 처음 진행하는 프로젝트다보니 테스트코드를 작성할 여유도 없었고, 어떤식으로 작성하는지도 몰랐기 때문에 테스트코드 없이 postman을 이용해 직접 테스트하며 구현했었는데, 나중에 리팩토링을 하려니 문제가 생겼다.

기존 변수명,함수명, 클래스 구조 등이 바뀌다 보니 예상치 못한 에러가 많이 발생해서 어려움을 겪었는데 테스트코드가 있었다면 이 과정이 훨씬 편해졌을 것이란걸 알고서 테스트코드의 필요성을 느꼈다.

 

이런 이유로 spring mvc의 테스트 코드 작성법을 공부하고 조금씩 추가할 계획이다.

또한 기본적으로 스프링부트 환경에서 테스트를 할때는 @SpringBootTest 어노테이션을 이용하면 편리하게 통합테스트를 진행할 수 있지만, 이는 다소 무겁기 때문에 속도가 느려서 사용하지 않고 단위테스트로 구분하여 작성하려 한다.

 

먼저 현재 진행하고 있는 프로젝트는 플러터와 통신하는 rest api로 구현되어있다.

도메인 별로 controller - service - repository 구조를 가지고 있으며, 가장 안쪽의 작은 기능부터 테스트코드를 작성해보면서 테스트 코드에 익숙해 지려한다.

 

  • memberRepository
public interface MemberRepository extends JpaRepository<Member,String>,MemberProfileRepository {
    @EntityGraph(attributePaths = "roleSet")
    @Query("select m from Member m where m.memberId = :memberId and m.social = false")
    Optional<Member> getWithRoles(@Param("memberId") String memberId);
.
.
.
}
 

Spring Data JPA를 이용해 repository를 사용하며 queryDSL을 사용하는 MemberProfileRepository가 함께 있다.

 

  • memberRepositoryTests
@DataJpaTest
@Import(QuerydslConfig.class)
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class MemberRepositoryTests {
    @Autowired
    private MemberRepository memberRepository;

    @DisplayName("회원가입")
    @Test
    void joinMemberTest() {
        // given
        Member member = member("testcode999");

        // when
        Member save = memberRepository.save(member);

        // then
        assertThat(save.getMemberId()).isEqualTo(member.getMemberId());
        assertThat(save.getMemberPassword()).isEqualTo(member.getMemberPassword());
    }

.
.
.

    private Member member(String name){
        return Member.builder()
                .memberId(name).memberPassword("a1234567").gender('M').nickName(name)
                .birthDay(LocalDate.now()).del(false).height(180L).weight(70L).name("테스트")
                .phone("01012345678").profilePhoto(null).social(false).roleSet(Collections.singleton(MemberRole.USER))
                .build();
    }
}
 
  • @DataJpaTest : JPA 컴포넌트를 테스트 하기 위한 어노테이션. 어노테이션 내부로 들어가면 기본적으로 @Transactional을 적용하고있으며 내장 DB를 사용하는 것이 기본값.
  • @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) : 내장 DB가 default이기 때문에 설정해놓은 DB를 사용하기위해 붙여준다.
  • @Import(QuerydslConfig.class) : memberRepository가 queryDSL을 사용하는 MemberProfileRepository 을 함께 상속하기때문에 queryDSL설정파일을 포함시켜준다.
  • 테스트하기 위한 memberRepository는 @Autowired를 통해 주입받는다.

 

 

단위 테스트를 할때 주로 많이 사용하는 템플릿으로 given-when-then 구조가 있다. (intellij의 라이브템플릿 기능으로 등록해두면 편함)

@DisplayName(테스트 이름표시)
@Test
void 테스트함수명() {
    // given
    필요한 데이터 초기화
    // when
    동작
    // then
    결과
}
 

위 코드의 예시에서는 Member변수를 생성한 후 repository에 저장하는 동작을 실행하고, 생성한 멤버와 저장된 멤버의 값이 맞게 저장되었는지 비교한다.

 

결과

 

 

728x90
반응형