이번 포스팅에서는
서비스를 생성하고, 동작이 원활히 수행되는지 테스트를 해야합니다.
- main 메소드를 사용하여 출력하기
- 직접 DB에 넣고 실행해보기
등등 다양한 방법으로 테스트를 할 수 있습니다.
이번 시간에는 Spring으로 Service를 만들며 굉장히 편리한 Test Case를 활용하여 테스트를 수행하는 방법을 알아보도록 하겠습니다.
Test Case
test파일에서 Class를 생성하여 주시고 작업을 수행하면 됩니다.
메소드에 @Test라는 anotation만 붙여주고 사용하면 됩니다.
예시로 간단한 스펙의 서비스를 만들어보겠습니다.
public int join(Member member) {
nameCheck(member);
repository.save(member);
return member.getNumber();
}
private void nameCheck(Member member) {
repository.findByName(member.getName())
.ifPresent(
m -> {throw new IllegalStateException("이미 존재하는 이름");}
);
}
회원가입 서비스를 만들었습니다. 예외상황으로 동일한 이름이 들어오는 경우 회원가입을 못하게 되어있습니다.
위 서비스가 잘 작동이 되는지 테스트를 위해 TestCase를 작성해보겠습니다.
*findByName(Member m)은 Optional변수를 반환하여 ifPresent를 사용할 수 있습니다.
@Test
public void 회원가입() {
//given
Member member1 = new Member();
member1.setName("김진섭");
Member member2 = new Member();
member2.setName("김진섭");
Member member3 = new Member();
member3.setName("김길동");
//when
Service.join(member1);
Service.join(member3);
IllegalStateException e = assertThrows(IllegalStateException.class, () -> Service.join(member2));
//then
assertThat(e.getMessage()).isEqualTo("이미 존재하는 이름");
}
제작한 회원가입 서비스에서는 동일한 이름으로 가입이 불가하게 만들었습니다.
회원가입을 위해 member를 3개 만들고, 직접 가입을 시켜보겠습니다.
위 코드에서 반드시 기억해야하는 것이 있습니다.
1. junit의 jupyter.api.Test anotation
2. assertj의 assertThat과 assertThrows
assertj의 assertThat은 여러가지 기능이 있는데, isEqualTo를 사용하면 두개의 값이 같은지 확인해줍니다.
결과가 원하는 결과가 나오는지 확인할 수 있고, 원하는 결과가 나오지 않았다면 에러메세지로 결과를 보여줍니다.
assertThrows는 왼쪽 예외와 오른쪽에 결과 예외가 같은지 확인하여줍니다.
TestCase 오류
테스트케이스를 잘 작성하여도 오류가 발생할 수 있습니다. 테스트케이스가 정해진 순서대로 실행되지 않으며 repository를 공유하기 때문입니다.(Concurrent하게 동작한다는 표현이 맞는 표현인지 모르겠습니다..)
개발자가 테스트 A B C를 구현하였다고 생각해보겠습니다.
개발자는 A -> B -> C 순서로 프로그램을 구현하였습니다.(그리고 실행도 A->B->C순으로 될 것이라고 생각하며 구현합니다.)
A 테스트는 데이터를 2개 넣고 2개인지 확인하는 테스트입니다.
B 테스트는 데이터를 5개 넣고 5개인지 확인하는 테스트입니다.(오류 확인)
C 테스트는 데이터를 1개 넣어보는 테스트입니다.
테스트는
A -> B -> C (B에서 오류 : 데이터 8개)
A -> C -> B (B에서 오류 : 데이터 8개)
C -> B -> A (A에서 오류 : 데이터 8개)
등등의 순서로 실행되며 기대한 값이 나오지 않을 수 있습니다.
서두가 길었는데, 위 문제를 해결하기 위해서는 테스트가 종료된 후 Repository를 초기화 시켜주면 됩니다.
@AfterEach
public void afterEach(){
repository.clean();
}
@BeforeEach
public void beforeEach(){
Service = new MemberService(repository);
}
@AtferEach라는 anotation을 붙여주면 각각의 테스트 케이스 실행 후 동작하게 됩니다.
그 와 반대로 테스트 케이스 시작 전에 실행시키고 싶다면 @BeforeEach anotation을 사용하면 됩니다.
포스팅을 마치며..
대학교 1학년 때부터 Java를 공부해서 거의 6년 가까이 자바를 사용했는데 Spring을 배워보니 먼가 새로운 언어를 배우는 느낌이네요.. 6년동안 자바를 알고 있었으면서 너무 늦게 스프링을 공부하는 것 같습니다.. ㅜㅜ 늦은만큼 열심히 배워야겠네요!
위 포스팅은 김영한님의 강의를 듣고 작성해둔 포스팅입니다.
김영한 개발자님이 TestCase를 제작할 때 처음이라면 아래 3가지를 염두하고 작성하면 도움이 될것이라는 조언을 해주신 것입니다.
1) given : 테스트를 위해 필요한 변수 선언
2) when : 테스트를 수행(service)
3) then : 결과 확인(assertions)
아직 많이 배워야하는 수준이기에.. 스프링 공부를 하며 참고하면 좋은 블로그나 혹은 관련 정보를 댓글로 공유해주시면 감사하겠습니다!!
감사합니다!
'Back-end > Spring' 카테고리의 다른 글
Request Body 받아오기 (0) | 2021.11.04 |
---|---|
Request Parameter 가져오기 (0) | 2021.11.04 |
스프링 빈 등록방법과 사용예시 (0) | 2021.07.30 |
Static,MVC,API (0) | 2021.07.15 |
Project 생성, View, Build (0) | 2021.07.15 |