Spring Boot를 이용하여 간단한 회원서비스를 만들어보았다.
클라이언트의 요청 중 데이터 저장소를 정하지 않았기 때문에 repository는 유동적으로 설정했고 최소한의 볼륨을 잡고 CRUD를 구현해 봤다.
// 가입된 사용자 검증
package hello.hellospring.repository;
import hello.hellospring.domain.Member;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.*;
public class MemoryMemberRepositoryTest {
@Test
public void findByName(){
// ---------임의회원 2명 가입시키기---------
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.getName());
}
}
// 결과: Test 실패
member1의 name이 데이터저장소에 정상적으로 저장되었는지 확인하는 테스트 코드를 구현했으나 불일치로 테스트에 실패했다.
이렇게 실패했다.
나는 당연히 .getName()을 하면 member1에 저장된 name값(="spring1")이 반환될 줄 알았는데 둘 중 하나는 객체의 주소값이 반환된 것 같다.
어떤 게 문제인지 하나씩 출력해 봤다.
result, member1 모두 객체의 주소값이 나오고 그 값은 동일했다.
그럼 "sprign1"으로 출력된 게 member1일까?
👉 맞다.
public class MemoryMemberRepository implements MemberRepository {
@Override
public Optional<Member> findByName(String name) {
return store.values().stream()
.filter(member -> member.getName().equals(name))
.findAny();
}
}
내가 만든 이 코드의 문제점은 findByName이 name= "spring1"인 Member 객체를 찾아서 그 결과를 result 변수에 담아준다는 것이었다.
findByName의 형태는 Optional <Member>
이기 때문에 .get()을 이용하여 name= "spring"인 Member객체로 가져온 것이지 name의 값인 "spring1"만 가져온 게 아니었다.
따라서 (객체 == 필드값)의 형태로 요청이 되었기 때문에 당연히 불일치로 나올 수밖에 없었다.
객체 == 객체
필드값 == 필드값
이렇게 형태를 맞춰서 비교하면 된다.
결과:
코드를 구현했다면 Test를 반드시 진행해봐야 한다.
Test를 진행할 때는 확인할 코드가 어떤 형태로 반환되는지를 꼭꼭 체크해야 한다.
지금처럼 Assertions.assertThat().isEqualTo(); 를 사용할 때 테스트에 실패할 경우 반드시 기댓값과 실제값을 확인해서 어느 부분이 문제인지를 빠르게 파악 후 코드를 수정해야 한다.
테스트코드를 만드는 게 어색하기도 하고 어렵기도 했는데 이번 기회를 통해 빨리 더 다양한 실패를 접해서 이런 참고사례를 만들어야겠다는 의욕이 생겼다.