> For the complete documentation index, see [llms.txt](https://heunnajo.gitbook.io/jpa/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://heunnajo.gitbook.io/jpa/4./undefined-2.md).

# 회원 기능 테스트

테스트 내용

1. 회원 가입 성공
2. 회원 가입 시 중복 회원 처리

<기술 설명>

1\. **@SpringBootTest** : 스프링 부트 띄우고 테스트(이게 없으면 @Autowired 다 실패)\
2\. **@RunWith(SpringRunner.class)** : 스프링과 테스트 통합\
3\. **@Transactional** : 반복 가능한 테스트 지원, 각각의 테스트를 실행할 때마다 트랜잭션을 시작하고 테스트가 끝나면 트랜잭션을 강제로 롤백 (이 어노테이션이 테스트 케이스에서 사용될 때만 롤백)\
테스트 코드에 @Transactional : 트랜잭션 커밋하지 않고 롤백한다.\
영속성 컨텍스트를 flush(트랜잭션 커밋)하지 않는다.\
DB 전략마다 다르긴 하지만 기본 generate에서는 save()에서 em.persist(member)를 해도 DB에 insert쿼리 적용되지 않는다!**왜냐하면 트랜잭션이 커밋될 때** DB에 쿼리가 들어가기 때문이다! (이러한 이유로 JPA 트랜잭션 커밋이 중요해진다.)

![](/files/-MeNSbiFdnNrKWF_FebN)

insert쿼리가 들어간 것 확인하는 방법

&#x20; ① @Rollback(false)

![](/files/-MeNRgMFlMsn2-YIlray)

![](/files/-MeNTy9RpyY6vl96z8dr)

&#x20; ② @Autowired EntityManager em 추가하고 em.flush()\
em.flush() : DB에 영속성 컨텍스트 쿼리 들어간다!\
assert 검증문 전에 em.flush()를 하면 최종 테스트 롤백되기 전에 로그로 insert문 확인 가능

<테스트 코드 구현>

1. 회원 가입

   ```
   @Test
   public void 회원가입() throws Exception {
     //Given
     Member member = new Member();
     member.setName("kim");
     //When
     Long saveId = memberService.join(member);
     //Then
     assertEquals(member, memberRepository.findOne(saveId));
   }
   ```

2\.  회원 가입 시 중복 회원 처리\
정상 테스트 : 예외가 터지는 것이 정상이므로 테스트 결과는 "실패" 처리되는 것이 맞다.\
\&#xNAN;**=>@Test(expected = IllegalStateException.class)**\
**@Test에 예상되는 에러를 expected로 넣어주면 try-catch문 없이 테스트 코드 작성 가능하다!**

**중복 회원 존재 시에 로직 상 익셉션이 터지고 리턴되야 정상이다. 그렇기 때문에 테스트 코드에서 더 밑으로 내려가면 안 된다.**\
Assert.fail() : 코드 돌다가 fail 있는 부분까지 오면 안 되도록 한다.(테스트 에러 발생)

```
@Test
public void 중복_회원_예외() throws Exception{
    //given
    Member member1 = new Member();
    member1.setName("Jo");

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

    //when : 동일한 이름을 넣었을 때
    memberService.join(member1);
    try{
        memberService.join(member2);
    }catch(IllegalStateException e){
        return;
    }

    //then : 예외가 발생해야 한다!!!
    fail("예외가 발생해야 한다");

}
```

```
@Test(expected = IllegalStateException.class)
public void 중복_회원_예외() throws Exception {
  //Given
  Member member1 = new Member();
  member1.setName("kim");
  Member member2 = new Member();
  member2.setName("kim");
  //When
  memberService.join(member1);
  memberService.join(member2); //예외가 발생해야 한다.
  //Then
  fail("예외가 발생해야 한다.");
}
```

* 테스트 케이스를 위한 설정\
  (운영 설정과 테스트 설정은 별도로 두는 것이 맞다.)

테스트는 케이스 격리된 환경에서 실행하고, 끝나면 데이터를 초기화하는 것이 좋다. 그런 면에서 메모리 DB를 사용하는 것이 가장 이상적이다.

**외부 DB가 아닌 Java 내부에 작은 메모리 DB를 만들어서 테스트하는 방법**

1. test에 resources 디렉토리 추가 후 main의 application.yml 복사\
   운영시에는 main이 우선권 갖지만, 테스트 시에는 test가 우선권 갖는다.\
   고로 테스트 시에는 test>resources>application.yml이 우선적으로 설정파일이 된다!
2. **JBC** datasource를 url이 아니라 **메모리로** 바꾸면 된다! (**메모리 모드로 변경**)\
   **jdbc:h2:mem:test**

**스프링부트에서는 기본적으로 별도 설정이 없으면 메모리모드로 돌리기** 때문에 위의 것을 설정하지 않아도 된다!

**스프링 부트 JPA**는 **기본적으로** ddl-auto가 **create-drop**으로 돌아간다!!!\
ddl-auto : create = 테이블이 존재하면 drop하고 create해서 애플리케이션 실행.\
**ddl-auto : create-drop = create와 동일한데 애플리케이션 종료 시점에 drop해서 다 날려준다.(깔끔하게 자원 초기화 가능)**\
**WAS가 내려가면 다 종료되기 때문에 create-drop으로 하지 않아도 되긴하다.**
