실전! 스프링 부트와 JPA 활용1(웹 애플리케이션 개발)

Ch04. 회원 도메인 개발 - 회원 기능 테스트

webmaster 2021. 12. 5. 17:18
728x90

테스트 요구사항

  • 회원가입을 성공해야 한다.
  • 회원가입할 때 같은 이름이 있으면 예외가 발생해야 한다.
@SpringBootTest
@Transactional
class MemberServiceTest {

    @Autowired MemberService memberService;

    @Autowired MemberRepository memberRepository;

    @Autowired
    EntityManager em;
    @Test
    public void 회원가입() throws Exception{
        //given
        Member member = new Member();
        member.setName("kim");

        //when
        Long saveId = memberService.join(member);
        //쿼리를 확인해보니 Insert를 실행하지 않는다.
        //why? JPA가 Transaction commit을 할때 저장이 실행이 되기 때문(em.persist 를 하더라도 시작되는것이 아니다.)
        //Test에서 @Transactional어노테이션이 달릴경우 기본으로 Rollback이 실행되기 떄문에 insert가 실행되지 않는것이다.
        //em.flush();

        //then
        assertEquals(member,memberRepository.findOne(saveId));
    }
    
    @Test()
    public void 중복_회원_예약() throws Exception{
        //given
        Member member1 = new Member();
        member1.setName("kim1");

        Member member2 = new Member();
        member2.setName("kim1");

        //when
        memberService.join(member1);
        assertThrows(IllegalStateException.class,() -> memberService.join(member2));
        //JUnit5 에서 제공하는 Exception을 잡는 방식
        //then
        //위에서 에러가 발생해서 여기까지 코드가 흐르게 되면 안된다,
        //fail("예외가 발생해야 한다.");//코드가 여기까지 오면 안된다.
    }
}
  • @SpringBootTest : 실제 서버를 띄우는 것처럼 테스트를 진행
  • @Transactional : Test에 해당 어노테이션을 붙이게 될 경우 테스트를 실행한 뒤, Rollback을 해준데
  • 회원가입 메서드
    • given : 초기 세팅
    • when : 언제
    • then : 검증
  • 같은 영속성 컨택스트 안에서는 PK가 같은 경우 같은 객체로 인식하기 때문에 save 한 객체와 find 한 객체는 같아야 한다.
  • join 메서드를 실행했지만 Insert 쿼리가 실행되지 않는 이유? 영속성 컨택스트가 실제 DB에 Commit을 할 때, Insert쿼리를 만들어 실행을 시켜주지만 현재는 Test이기 때문에 @Transactional이 롤백을 해준다. 그렇기 때문에 실제 Insert 쿼리가 실행되지 않는 것이다.
    • 실제 Insert쿼리를 확인하고 싶다면 영속성 컨택스트의 flush() 메서드를 실행해 주거나 Rollback 옵션을 false로 변경해 주면 된다.
  • 중복_회원_예약 메소드
    • 중복된 회원을 넣을 경우 에러가 검증이 되는지 확인하는 메서드이다.
    • Junit5 에서는 assertThrows로 해당 메서드에서 해당 Exception이 발생하는지 검증이 가능하다.

참고: 테스트 케이스 작성 고수 되는 마법: Given, When, Then (http://martinfowler.com/bliki/GivenWhenThen.html)

이 방법이 필수는 아니지만 이 방법을 기본으로 해서 다양하게 응용하는 것을 권장한다.

InMemory DB Test

Test를 진행하기 위해서 Test와는 별개의 문제인 DB설치를 해줘야 하는 단점이 있다.

이를 해결하기 위해 SpringBoot에서는 Inmemory DB를 제공해 준다.

dependency의 H2 인메모리 DB를 사용할 수가 있다. 

test의 Yml 파일 복사
url 변경
주석 처리 하여도 상관 없다.

  • test와 운영에서의 application 설정이 같을 수 없기 때문에 따로 분리하는 것이 맞다.
  • URL을 test 인메모리 DB로 변경해 주면 된다.
  • 사실 application 설정을 모두 지우게 되면 SpringBoot가 알아서 InMemoryDB에 create-drop으로 설정하여 준다.
728x90