개발한 기능이 정상 동작하는지 검증하는 방법에는 main메소드를 실행하거나 controller를 실행하는 등의 방법이 있지만 이런 경우는 테스트를 한꺼번에, 많이, 자주 실행하기 어렵다.
따라서 테스트 케이스를 작성하고 테스트 코드를 실행하여 동작을 검증해야한다.
테스트 코드는 java패키지가 아닌 test패키지 내부에 작성한다. 나는 MemoryMemberRepository를 테스트할 것이므로 repository패키지를 만들고 그 내부에 MemoryMemberRepositoryTest
클래스를 작성한다.
여기서는 JUnit 테스트 도구를 이용하여 테스트를 진행한다.
save
메소드 먼저 작성해보자.
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();
Assertions.assertEquals(member, result); //expected, actual
}
asserEquals(expected,actual)
메소드는 expected와 actual이 같으면 테스트를 통과시키는 메소드이다.
여기서는 테스트 케이스에서 임의로 넣어준 member와, 실제로 db에 저장되어 있는 result가 같으면 테스트를 통과한다.조금 더 쉬운 방법
assertThat(member.equalTo(result))
테스트를 통과하면 위와 같은 초록색 체크 표시를 볼 수 있다.
테스트가 실패하면 어떻게 뜰까? asset 메소드 부분을 Assertions.assertEquals("fail", result);
이라고 바꾸면 테스트가 실패한다.
findByName과 findAll도 작성해준다.
@Test
public void findByName() {
Member member1 = new Member();
member1.setName("spring1");
repository.save(member1);
Member member2 = new Member();
member2.setName("spring2");
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("spring2");
repository.save(member2);
List<Member> result = repository.findAll();
assertThat(result.size()).isEqualTo(2);
}
이 때 개별 테스트를 실행하면 테스트가 통과되지만 클래스 단위로 테스트를 실행하면 테스트가 통과되지 않는다.
그 이유는 테스트가 실행되는 순서가 보장되지 않기 때문이다. 모든 테스트는 순서와 의존적이지 않게 설계해야 한다.
이를 해결하려면 하나의 테스트가 끝날 때마다 레포지토리를 지워줘야한다.
따라서 @AfterEach
애노테이션을 사용하여 레포지토리를 clear해야한다.
@AfterEach
public void afterEach() {
repository.clearStore();
//MemoryMemberRepository에 clearStore라는 함수를 만들어야함!
}
이렇게 각 레포지토리를 clear하는 코드를 추가하면 클래스 단위로 테스트를 진행해도 모두 통과되는 것을 볼 수 있다!