Spring-회원 Repository test case 작성

snowball moon·2023년 10월 2일
0

Spring-입문

목록 보기
10/14
post-thumbnail

회원 repository test case

회원 repository 클래스가 원하는 대로 동작하는지 검증하는 방법이 있는데 이때 test case를 작성해서 검증을 한다. 코드를 코드로 작성해서 검증하는 것이다.

개발한 기능을 실행해서 테스트 할 때 자바의 main 메서드나 웹 애플리케이션의 컨트롤러를 통해 해당 기능을 실행하는데 이러한 방법은 시간이 오래 걸리고 반복 실행하기가 힘들고 여러 테스트를 한번에 실행하기 어렵다는 단점이 있다.

그래서 Java는 JUnit이라는 프레임워크로 테스트를 실행하여 위와 같은 문제를 해결한다.

먼저 src/test/java에 repository package를 생성한 후 MemoryMemberRepositoryTest class를 만든다.

save 테스트

@Test
 public void save() {
 //given
 Member member = new Member();
 member.setName("spring");
 //when
 repository.save(member);
 //then
 Member result = repository.findById(member.getId()).get();
 assertThat(result).isEqualTo(member);
 }

먼저 save 기능이 동작하는지 본다.

member.setName으로 이름을 세팅해주고 repository에 save를 하는데 findById로 넣은 값이 제대로 들어가는지 검증한다.

Optional에서 값을 꺼낼 때에는 get으로 꺼낼 수 있다. 꺼낸 후 result라고 하면 위에서 저장한 것과 DB에서 꺼낸 것이 똑같으면 참이다.

System.out.println("result="+(result==member));

(result가 member와 같은지)

result가 true라고 뜨는데 계속 글자로 볼 수 없기 때문에 assert라는 기능을 쓴다.
org.junit에 jupiter가 제공하는 assertions에 assertEqulas를 사용한다.

org.junit.jupiter.api.Assertions.assertEquals(member,result);

저장된 member가 find 했을 때 나와야 한다.

실행이 되는데 null을 넣으면

기대한 값이 아니라서 오류가 뜬다.

org.assertj를 사용해서 해보면

 Assertions.assertThat(member).isEqualTo(result);

assertThat이라는 문법을 사용하고 member는 isEqulaTo 말 그대로 결과를 가지 result와 똑같다는 의미를 가진다.

Assertions 부분은 static import 해준다.

assertThat(member).isEqualTo(result);

여기에도 null을 넣어보면 오류가 발생한다.

실무에서는 build tool과 엮어서 오류 테스트 케이스를 통과하지 못하면 다음 단계로 넘어가지 못하도록 막아버린다.

findByName 테스트

//given
 Member member1 = new Member();
 member1.setName("spring1");
 repository.save(member1);
 Member member2 = new Member();
 member2.setName("spring2");
 repository.save(member2);

member1, member2 즉 spirng1, spring2라는 회원 가입된 것이다.

이제 findByName이 잘 동작하는지 테스트 해보자
repository.findByName을 사용해서 spring1을 찾아본다.

Member result = repository.findByName("spring1").get();
assertThat(result).isEqualTo(member1);

get으로 꺼내면 옵션을 한 번에 꺼낼 수 있고 assertTaht으로 member1과 똑같다 라고 해준다.

실행시키면 잘 뜨는데 spring2로 바꿔보면

다른 객체라서 오류가 뜬다.

findAll 테스트

@Test
 public void findAll() {
 //given
 Member member1 = new Member();
 member1.setName("spring1");
 repository.save(member1);
 Member member2 = new Member();
 member2.setName("spring2");
 repository.save(member2);
 //when
 List<Member> result = repository.findAll();
 //then
 assertThat(result.size()).isEqualTo(2);
 }

2를 넣을 때에는 잘 돌아가는데 3을 넣으면 기대하는 값이 아니기 때문에 오류가 뜬다.

다시 2를 넣고 전체 테스트를 돌리면 오류가 발생하는데
모든 테스트는 순서와 관계 없이 메서드별로 모두 따로 동작하게 설계해야 한다.
현재 findAll이 먼저 실행이 되었는데 순서에 의존적으로 설정하면 안된다.

spring1,spring2가 이미 저장되었기 때문에 findByName에서 다른 객체가 이전에 저장했던 spring1이 나온것이다.

이럴 때에는 test가 하나 끝나면 이 데이터를 모두 클리어 해줘야 한다.

MemoryMemberRepository class에서 아래 코드를 넣어준다.

   public void clearStore() {
        store.clear();
    }

store.clear는 모두 비워주는 역할을 한다.

MemoryMemberRepositoryTest에서는 아래 코드를 추가해준다.

  @AfterEach
    public void afterEach() {
        repository.clearStore();
    }

@AfterEach는 메서드 실행이 끝날 때마다 동작하는데 콜백 메서드라고 보면 된다.

이렇게 되면 테스트가 실행 되고 끝날 때마다 한 번씩 저장소를 다 치워주게 되고 순서와 상관이 없어져서 오류가 발생하지 않는다.

테스트는 서로의 순서와 관계가 없어야 하고 의존 관계 없이 설계되어야 하기 때문에 하나의 테스트가 끝날 때마다 저장소나 공용 데이터들을 모두 지워줘야 한다.

TDD

test class를 먼저 작성 한 다음 repository를 작성할 수도 있는데
이렇게 순서를 뒤집어서 하는 것을 테스트 주도 개발이라고 해서 TDD라고 한다.

TDD(Test Driven Development)는 소프트웨어 개발 방법 중 하나이며 테스트 코드를 먼저 작성하고 이후 그에 대한 코드를 작성하는 방법이다.

TEST FAILS 단계: 실패하는 테스트 코드를 먼저 작성
TEST PASSES: 성공시키기 위한 실제 코드 작성
REFACTOR: 중복 코드를 제거, 일반화 등의 리팩토링 수행하여 코드의 유지 보수 및 가독성을 높여줌

TDD의 장점은 튼튼한 객체 지향적인 코드를 생산해주고 재설계 시간과 디버깅 시간을 단축해주며 테스트 문서가 대체 가능하고 추가 구현이 용이해진다.
그러나 생산성이 저하되는 단점이 있기 때문에 일반적인 개발 방식에 비해 시간이 늘어난다.

TDD의 대표적인 Tool로는 Junit이 있다.

1.@AfterEach : 한번에 여러 테스트를 실행하면 메모리 DB에 직전 테스트의 결과가 남을 수 있다. 이렇게
되면 다음 이전 테스트 때문에 다음 테스트가 실패할 가능성이 있다. @AfterEach 를 사용하면 각 테스트가
종료될 때 마다 이 기능을 실행한다. 여기서는 메모리 DB에 저장된 데이터를 삭제한다.
2.테스트는 각각 독립적으로 실행되어야 한다. 테스트 순서에 의존관계가 있는 것은 좋은 테스트가 아니다.

References

스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술 https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%9E%85%EB%AC%B8-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8
https://hanamon.kr/tdd%EB%9E%80-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%A3%BC%EB%8F%84-%EA%B0%9C%EB%B0%9C/

0개의 댓글