이번에는 저번 글에서 만든 회원 서비스의 테스트 케이스를 작성해 제대로 동작하는지 확인할 것이다.
첫 번째 기능이었던 회원 가입 기능의 테스트 케이스를 작성했다.
// test/java/hello.hello_spring/service/MemberServiceTest.java
package hello.hello_spring.service;
import hello.hello_spring.domain.Member;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
import static org.assertj.core.api.Assertions.*;
class MemberServiceTest {
MemberService memberService = new MemberService();
@Test
void join() {
Member member = new Member();
member.setName("hello");
long saveId = memberService.join(member);
Member findMember = memberService.findOne(saveId).get();
Assertions.assertThat(member.getName()).isEqualTo(findMember.getName());
}
}
단순히 member를 생성해 회원으로 잘 등록이 되는지 확인하는 테스트 케이스다.
하지만 회원 서비스를 생성할 때 단순한 등록뿐만 아니라 중복인 이름이 있는지 확인하는 기능도 있었다.
그래서 중복 이름을 체크하는 테스트 케이스도 작성해주었다.
// service/MemberServiceTest.java
@Test
public void duplicateNameCheck() {
Member member1 = new Member();
member1.setName("spring");
Member member2 = new Member();
member2.setName("spring");
memberService.join(member1);
IllegalStateException e = assertThrows(IllegalStateException.class, () -> memberService.join(member2));
assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다.");
}
이름이 spring으로 같은 member1, member2를 생성하고 member1을 먼저 회원 가입으로 저장소에 등록했다.
그리고 member2로 회원 가입을 시도하면 에러가 발생해야 한다.
getMessage 메서드와 isEqualTo를 사용해 에러 메시지가 일치하는지 확인했고 테스트는 성공적이었다.

이 테스트 케이스들에서는 케이스마다 member의 이름을 다르게 사용해서 문제가 발생하지는 않았다.
하지만 그래도 문제가 발생할 수 있으니 이전에 작성했던 테스트 케이스처럼 저장소를 초기화하는 기능을 추가해주었다.
// service/MemberServiceTest.java
...
import hello.hello_spring.repository.MemoryMemberRepository;
import org.junit.jupiter.api.AfterEach;
class MemberServiceTest {
MemberService memberService = new MemberService();
MemoryMemberRepository memberRepository = new MemoryMemberRepository();
@AfterEach
public void afterEach() {
memberRepository.clearStore();
}
...
}
하지만 이렇게 추가하고 보니 테스트 케이스들마다 각각 저장소를 새로 생성해 테스트를 진행하고 있다.
문제가 생길 수 있으니 조금 수정해주었다.
// main/java/hello.hello_spring/service/MemberService.java
...
public class MemberService {
private final MemberRepository memberRepository;
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
...
}
// service/MemberServiceTest.java
...
import org.junit.jupiter.api.BeforeEach;
class MemberServiceTest {
MemberService memberService;
MemoryMemberRepository memberRepository;
@BeforeEach
public void beforeEach() {
memberRepository = new MemoryMemberRepository();
memberService = new MemberService(memberRepository);
}
...
}
이전에는 new MemoryMemberRepository()로 구현체를 직접 생성했지만 의존성 주입 방식으로 변경했다.
문제없이 성공적으로 테스트 결과를 볼 수 있었다.

의존성 주입은 객체가 자신의 의존성을 외부에서 주입받는 설계 패턴이다.
이 패턴은 객체 간의 결합도를 낮추고, 코드의 유연성과 테스트 용이성을 높일 수 있다.
의존성 주입은 크게 생성자 주입, 세터 주입, 필드 주입의 세 가지로 이루어지는데 앞선 테스트 케이스 작성에서 사용된 방식은 생성자 주입 방식이다.
생성자 주입은 생성자를 통해 의존성을 주입하는 방식이고 현재 가장 권장되는 방식이라고 한다.
다음 코드는 생성자 주입 방식의 예시이다.
@Service
public class MemberService {
private final MemberRepository memberRepository;
@Autowired
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}