본문 바로가기
Java | Spring/Spring 입문

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

by 동기 2021. 10. 5.
반응형

순서


3.3 회원 리포지토리 테스트 케이스 작성

개발한 기능을 실행해서 테스트 할 때, 자바의 main 메서드를 통해서 실행하거나 웹 애플리케이션의 컨트롤러를 통해서 해당 기능을 실행한다. 이러한 방법은 준비하고 실행하는데 오래 걸리고, 반복 실행하기 어렵고 여러 테스트를 한번에 실행하기 어렵다는 단점이 있다. 자바는 JUnit 이라는 프레임워크로 테스트코드를 작성,실행해서 이러한 문제를 해결한다.

 

repository 패키지와 MemoryMemberRepositoryTest 클래스 작성

 

MemoryMemberRepositoryTest 클래스

MemoryMemberRepository 객체를 인스턴스화 해준 후, save() 메서드를 작성하고, @Test 어노테이션을 추가한다.

그렇게 되면 save() 함수를 실행할 수 있다. 현재는 메서드내에 아무 내용도 없기때문에 성공적으로 passed가 뜬다.


save()메서드 내에 Member객체와 repository를 이용하여 테스트를 해 보자.

findById를 Optional로 작성하였으므로 , get() 으로 optional을 까서 값을 꺼낼 수 있다.(좋은 방법은 아님)

 

member 와 repository에서 꺼낸 member가 일치하는지를 확인할 수 있다.

 

 


글자로 계속 확인할 수도 있으나, Assertions(junit) 를 이용하여 확인할 수도 있다.

*assert (주장하다)

Assertions.assertEquals(기대값,실제값) 비교

 

테스트 성공

 


테스트 실패. Expected 값과 Actual값이 다름


또는 Assertions(org.assertj) 를 이용할 수도 있다.

 

※ Assertions ( command + Enter / alt + Enter ) 를 통해 static import를 할 수 있다.

그러게 되면 바로 assertThat을 사용 할 수 있다.


 

※빌드툴과 엮어서, Test 케이스를 통과하지 않으면 빌드하지 않도록 막을 수 있다.


다음으로 이름으로 찾는 findByName()을 테스트 해보자.

 

*같은 이름이 많을 경우 shift + f6 을 통해 해당 이름을 한번에 수정 할 수 있다.

 

2명의 멤버를 저장하고, result 객체와 각 멤버를 비교하는 테스트 케이스 이다.

현재는 spring1 이라는 이름의 회원이 result 객체 이므로, result 와 member1은 같다.

 


result 와 member2 를 비교할 시 

에러가 뜨게 된다.

 


Test 케이스의 장점은, 각 메서드를 같이 돌릴 수 있다.

 

클래스 레벨에서 돌리기

 

패키지 레벨에서 모든 클래스 돌리기

하위 패키지의 모든 테스트 클래스가 실행된다


findAll() 을 작성해보자.

Member 객체 2개를 저장 후, result List 에 findAll 메서드를 통해 나온 Member들을 저장한다.

result의 사이즈가 2개인지 확인

테스트 통과


자 이제 MemoryMemberRepositoryTest 클래스에는 save(), findByName(),findAll() 총 세개의 메서드가 있다.

클래스 단위로 실행을 해 보면

에러가 뜨며, 실행 순서또한 메서드를 작성한 순서대로 보장되지 않는 것을 알 수 있다.

 

에러의 원인은 findAll() 이 먼저 실행되며

findAll() 에서의 member1 과 member2에 spring1 과 spring2가 저장이 된다. 그래서 findByName() 이 실행 될 때, 앞서 repository의 map에 저장되어있던 spring1이 나오게 되어 에러가 난 것이다.

 

순서와 관계없이, 의존관계 없이 테스트가 끝날 시 공용 Data를 Clear 해 줘야 한다.

그러기 위해 어떠한 동작이 끝날때 마다 실행되는 함수가 있는데, @AfterEach 가 있다. 

 

MemoryMemberRepository 클래스에 clearStore() 메서드를 작성후. ( store map을 clear 하는 메서드) afterEach() 메서드에서 실행하도록 한다.

이렇게 작성하게 되면, 테스트가 실행되고 끝날때 마다 afterEach() 메서드가 실행되며 repository를 비우게 된다. 이렇게 되면 메서드 순서와 상관없이 에러가 발생하지 않고 정상 실행 된다.


이렇게 테스트 코드를 작성해 보았다.

테스트 코드 없이 개발은 혼자 할 때는 괜찮으나, 소스코드가 엄청 많아지거나, 여러명이 함께 개발할때는 테스트코드가 필수이다. 깊이있게 꼭 공부해보자

 

지금 방법은 구현 클래스 Repository를 작성 후, 맞는지 검증하는 과정으로 작성하였는데,

이것과 반대로 Test Class를 먼저 작성 후(틀 먼저) MemberMemoryRepository를 작성할 수도 있다. 이 방법을 TDD(Test-driven Development), 즉 테스트 주도 개발 이라고 한다.

 

다음시간에는 회원 비즈니스 로직이 들어가는 회원 서비스 클래스를 작성해 보자.


 

반응형

댓글