Development/Spring

스프링 입문 - 회원 리포지토리 테스트 케이스 작성

양선규 2023. 11. 1. 00:07
728x90
반응형

개발한 코드가 잘 동작하는지 확인하기 위해서는, 테스트 케이스를 작성하여 확인해야 한다.

자바는 JUnit 이라는 프레임워크를 제공하여, 테스트를 효율적으로 실시할 수 있게 해준다.

 

 

패키지 생성

 

우선 테스트 케이스를 작성할 패키지를 만들어 주자.

 

주의해야 할 점은, 앞서 코드를 작성했던 "Main" 디렉터리 밑이 아닌 그 아래에 있는 "test" 디렉터리 아래에 만들어야 한다는 점이다.

test 디렉터리 밑에서, hello.hellospring.repository 패키지를 만들어 주자.

 

 

MemoryMemberRepositoryTest

 

repository 패키지 아래에 MemoryMemberRepositoryTest 클래스를 만들어 주자.

우리는 MemoryMemberRepository를 테스트할 것이기 때문에, 뒤에 Test만 붙여서 생성하는 것이다.

 

 

클래스, 필드

 

테스트 클래스이다.

 

어차피 테스트만 수행할 것이기 때문에 클래스 선언부에 public은 뺐다.

필드엔 MemoryMemberRepository 객체를 생성해주자.

 

 

save() 메소드 테스트

 

첫번째 테스트 코드다.

 

member 객체를 만들어 name을 Spring으로 세팅했고, repository( MemoryMemberRepository 객체 )에 저장했다.

이후 repository.findById 메소드로, repository에서 ID를 기준으로 객체를 꺼내 result에 저장했다.

여기서 사실 Optional<Member> result = .... 이렇게 해야 하는데, 마지막에 get()을 사용함으로써 Optional 껍데기를 벗겨낸 것이다.

또한 save() 뿐만 아니라 findById() 메소드까지 사용했으므로, 둘 다 테스트하는 것과 같은 효과라고 볼 수 있다.

 

마지막으로 내가 저장한 member와 repository에 저장된 객체가 동일한지 확인한다.

마지막 2개의 코드는 member, result 두 객체가 같은 것인지 확인하는 코드이다. 두 코드는 문법만 다를 뿐 완전히 동일한 코드다.

위 코드를 먼저 쓴 후 alt+enter로 앞의 Assertions를 생략할 수 있기 때문에, 참고삼아 두개 다 적었다.

 

assertThat을 사용하면, 내가 일일이 테스트 결과를 확인할 필요 없이 테스트에 실패했을 경우 알아서 오류가 뜬다.

정상적으로 테스트 되었을 경우 정상 실행되므로, 꽤 편리한 기능이다.

 

 

findByName() 메소드 테스트

 

두번째 테스트 코드다.

 

일단 두개의 Member 객체를 생성해서 repository에 저장하고,

member1의 Name 값인 Spring1을 기준으로, findByName() 메소드를 사용해 repository에서 객체를 꺼내 result에 담았다.

 

마지막으로 member1과 result가 같은 객체인지 확인한다.

 

 

findAll() 메소드 테스트

 

마지막 테스트 코드다.

 

위와 마찬가지로 Member 객체 2개를 repository에 저장하고,

findAll() 메소드를 사용해 repository에서 모든 객체를 꺼내, 배열 형태로 result 변수에 담았다. findAll() 메소드 리턴타입이 배열이었기 때문이다.

 

마지막으로, size()메소드로 result의 길이를 측정하고 값이 2인지 확인한다. 우리는 객체 2개를 넣었으니 값이 2여야 정상이다.

 

이제 테스트를 해보자.

 

 

오류

 

오류가 난다. 왜일까?

 

이것은 매 테스트 케이스마다 저장소를 초기화시키지 않아서 생기는 문제이다.

왼쪽을 보면 findAll() 실행 후 findByName() 에서 오류가 났는데,

findAll()에서 저장했던 객체 2개가 findByName()에서도 사용되어 오류가 난 것이다.

 

따라서, 모든 테스트가 독립적으로 실행될 수 있도록 메소드 하나가 실행될 때마다 저장소를 초기화할 필요가 있다.

테스트는 테스트 순서에 영향을 받아선 안 되며, 독립적으로 실행되어야 좋은 테스트 코드다.

 

 

clearStore()

 

MemoryMemberRepository로 와서, 12행 ~ 14행에 보이는 clearStore() 메소드를 작성해주자.

store.clear() 메소드는 저장소를 깨끗이 지우는 메소드이다.

 

MemoryMemberRepositoryTest 아니다. MemoryMemberRepository 이다.

 

 

afterEach()

 

다시 MemoryMemberRepositoryTest 쪽으로 돌아와서, afterEach() 메소드를 만든다.

 

위에 @AfterEach 어노테이션을 꼭 붙여줘야 한다. 해당 어노테이션이 붙은 메소드는, 다른 메소드의 실행이 끝날 때마다 자동실행된다.

따라서, 테스트 코드가 하나 끝날때마다 저장소가 초기화되는 것이다.

 

이제 다시 테스트를 돌려보자.

 

 

성공

 

깔끔하게 테스트에 성공했다.

 

아래는 MemoryMemberRepositoryTest 전체 코드이다.

 

1
2
3

 

이렇게 테스트 케이스를 작성해서, 리포지토리 테스트를 성공적으로 해볼 수 있었다.

 

 

이번엔 구현 클래스 먼저 만들고 테스트 케이스를 작성했으나, 실무에서는 반대로 하는 방법도 많이 사용한다고 한다.

먼저 틀(테스트 케이스)부터 만들어놓고 그에 맞게 구현 클래스를 작성하는 방법인데, TDD(테스트 주도 개발) 이라고 한다.

728x90
반응형