들어가며
- 개발 한 기능을 테스트 하는 방법은 크게 두가지가 있다.
. main 을 통해 실행 하는 등 실제로 실행 하는 방법
. test 코드를 이용해 테스트 실행을 해 보는 방법
- 이번 시간에는 test 코드를 통해 기능이 재대로 개발 되었는지 오류 없이 실행 되는지 확인 해 보도록 하겠다.
test코드 디렉토리 구성
- main 디렉토리 아래 test 디렉토리에 main 과 유사하게 디렉토리를 구성 해 준다.
- 이번에는 저번 시간에 만들었던 repository 를 test 해 볼 것이기 때문에 이와 유사하게 구성 해 주고 test class 를 생성 해 준다.
- 코드를 작성 한다.
. 방법은 @Test 를 통해 아래의 함수가 test 코드임을 암시 한다.
. assertThat 을 통해 정상적인 값으로 실행 되었는지 확인 해 준다.
. 여기서는 "assertThat(A).isEqulTo(B)" 를 통해 비교 하는데 말 그래도 A 와 B 가 동일한지 확인 하는 코드이다.
- repository 의 기능 save, findByName, findAll 을 테스트 해 줄 것이다.
package com.example.learn_ex_member.repository;
import com.example.learn_ex_member.domain.Member;
import static org.assertj.core.api.Assertions.*;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import java.util.List;
public class MemoryMemberRepositoryTest {
MemoryMemberRepository repository = new MemoryMemberRepository();
@Test
public void save(){
Member member = new Member();
member.setName("spring");
repository.save(member);
Member result = repository.findById(member.getId()).get();
assertThat(member).isEqualTo(result); // 기대값인 member 가 result 와 동일 한가?
}
@Test
public void findByName(){
// 우선 두 명의 회원 정보를 저장 함
Member member1 = new Member();
member1.setName("spring1");
repository.save(member1);
Member member2 = new Member();
member2.setName("spring1");
repository.save(member2);
Member result = repository.findByName(("spring1")).get();
assertThat(result).isEqualTo(member1);
}
@Test
public void findAll(){
// 우선 두 명의 회원 정보를 저장 함
Member member1 = new Member();
member1.setName("spring1");
repository.save(member1);
Member member2 = new Member();
member2.setName("spring1");
repository.save(member2);
List<Member> result = repository.findAll();
assertThat(result.size()).isEqualTo(2);
}
}
- 위와 같은 방법으로 test 를 실행 시 개별 test code 를 실행하면 모두 문제 없이 실행 된다.
- 하지만 class 전체를 실행 하게 되면 에러가 뜨게 된다.
- 이는 findAll 과 findByName 에 둘다 member 변수를 저장 하는 과정이 있어 충돌이 나기 때문이다.
- 따라서 각 test 를 실행 한 후 clear 해 주는 과정이 필요하다.
AfterEach
- 위 기능을 제공해 주는 것이 바로 AfterEach 이다.
- 이는 각 test code 가 실행 완료 될 때 마다 실행 해 주는 것이다.
- 우선 repository 쪽에 메모리를 clear 해 주는 코드를 추가 해 준다.
//MemoryMemberRepository.java
public class MemoryMemberRepository implements MemberRepository {
//...
public void clearStore(){
store.clear();
}
}
- 그 후 repositoryTest 코드에 AfterEach 를 추가해 준다.
package com.example.learn_ex_member.repository;
import com.example.learn_ex_member.domain.Member;
import static org.assertj.core.api.Assertions.*;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import java.util.List;
public class MemoryMemberRepositoryTest {
MemoryMemberRepository repository = new MemoryMemberRepository();
@AfterEach
public void afterEach(){ // test 하나가 끝나고 난 후 실행 할 것
repository.clearStore(); // 하나의 함수를 실행 한 후 clear 필수
}
//...
}
- 이후 실행 하면 문제 없이 돌아 가는 것을 알 수 있다.
- 만약 기능에 문제가 생기면 에러가 뜬다.
main 코드와 Repository 일치
- 앞 시간에 Service 코드에서 Repository 를 받아 내부에서 넣어 준 적이 있었다.
- 그렇게 되면 Test 코드에서의 Repository 와 main 코드의 Service 코드의 Repository가 같아 지게 된다.
- 모든 코드 수행 전에 실행 되어야 하기 때문에 @BeforeEach 를 사용 하였다.
//MemberServiceTest.java
@BeforeEach
public void beforeEach(){
memberRepository = new MemoryMemberRepository();
memberService = new MemberService(memberRepository);
}
Test code exception 상황 발생시키기
- test code 는 오류 없이 잘 돌아 가는지 확인 하기 위한 수단이기도 하지만 예외처리가 잘 되는지 확인 하는 수단이기도 하다.
- MemberService 코드중 중복 회원 가입을 시도할 경우 Exception 이 발생 하니 이를 이용하여 구현 해 보겠다.
- 그리고 test code 는 given, when, then 형식으로 자주 쓴다고 하니 그렇게 구현 해 보았다.
- 우선 정상 적일때는 단순히 Member 데이터를 만들어 save 시켜 주면 된다.
//MemberServiceTest.java
@Test
void join() {
//given : 뭔가 주어짐
Member member = new Member();
member.setName("spring");
//when : 이때
Long saveId = memberService.join(member);
//then : 뭐가 나와야 한다
Member findMember = memberService.findOne(saveId).get();
Assertions.assertThat(member.getName()).isEqualTo(findMember.getName());
}
- 에러 상황일 때는 동일한 이름의 회원을 가입 시키는 경우다.
- 방법은 두가지가 있는데
. try - catch 문을 사용해 join() 시 exception 여부와 이때의 message 를 비교 한다.
. assertThrows를 사용하여 exception 여부와 이때의 message 를 비교 한다.
//MemberServiceTest.java
@Test
public void error_join(){
//given
Member member1 = new Member();
member1.setName("spring");
Member member2 = new Member();
member2.setName("spring");
//when
memberService.join(member1);
IllegalStateException e = assertThrows(IllegalStateException.class, () -> memberService.join(member2));
Assertions.assertThat(e.getMessage()).isEqualTo("존재하는 회원");
// try{
// memberService.join(member2);
// fail("예외가 발생해야 합니다.");
// } catch(IllegalStateException e){
// Assertions.assertThat(e.getMessage()).isEqualTo("존재하는 회원");
// }
}
- 전체 코드
//MemberServiceTest.java
package com.example.learn_ex_member.service;
import com.example.learn_ex_member.domain.Member;
import com.example.learn_ex_member.repository.MemoryMemberRepository;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.*;
class MemberServiceTest {
MemberService memberService;
MemoryMemberRepository memberRepository = new MemoryMemberRepository();
//MemberService.java 의 Repository 와 동일한 객체를 사용 하기 위한 작업
@BeforeEach
public void beforeEach(){
memberRepository = new MemoryMemberRepository();
memberService = new MemberService(memberRepository);
}
@AfterEach
public void afterEach(){ // test 하나가 끝나고 난 후 실행 할 것
memberRepository.clearStore(); // 하나의 함수를 실행 한 후 clear 필수
}
@Test
void join() {
//given : 뭔가 주어짐
Member member = new Member();
member.setName("spring");
//when : 이때
Long saveId = memberService.join(member);
//then : 뭐가 나와야 한다
Member findMember = memberService.findOne(saveId).get();
Assertions.assertThat(member.getName()).isEqualTo(findMember.getName());
}
@Test
public void error_join(){
//given
Member member1 = new Member();
member1.setName("spring");
Member member2 = new Member();
member2.setName("spring");
//when
memberService.join(member1);
IllegalStateException e = assertThrows(IllegalStateException.class, () -> memberService.join(member2));
Assertions.assertThat(e.getMessage()).isEqualTo("존재하는 회원");
// try{
// memberService.join(member2);
// fail("예외가 발생해야 합니다.");
// } catch(IllegalStateException e){
// Assertions.assertThat(e.getMessage()).isEqualTo("존재하는 회원");
// }
}
}
'백앤드 > SpringBoot + Java 간간한 백앤드 예제' 카테고리의 다른 글
[SpringBoot + Java] 간단한 백엔드(MySql) (0) | 2023.07.20 |
---|---|
[SpringBoot + Java] 간단한 백엔드(Spring Bean) (0) | 2023.07.18 |
[SpringBoot + Java] 간단한 백엔드(domain, repository, service) (0) | 2023.07.16 |
[SpringBoot + Java] 스프링 웹(Static, MVC, API) (0) | 2023.07.11 |
[SpringBoot + Java] 프로젝트 생성 + 실행 (0) | 2023.07.10 |