Spring-회원 서비스 테스트

snowball moon·2023년 10월 5일
0

Spring-입문

목록 보기
12/14

회원 서비스 test case

MemberService class에서 단축키 Ctrl+Shift+T를 사용하면 Create New Test가 뜨는데

Test를 할 수 있도록 자동 생성해준다.

(테스트코드는 실제코드에 포함되지 않기 때문에 한글을 사용해도 괜찮다.)

@Test
    void 회원가입() {
        //given
        Member member=new Member();
        member.setName("hello");

        //when
        Long saveId=memberService.join(member);

        //then
        Member findMember=memberService.findOne(saveId).get();
        Assertions.assertThat(member.getName()).isEqualTo(findMember.getName());

    }

멤버 서비스에서 findOne으로 찾아도 되는데 저장한 것이 repository에 있는 것이 맞는지 확인해야 한다.

실행해보면 회원가입은 잘 만들어진 것을 알 수 있다.

테스트는 정상플로우도 중요하지만 예외플로우가 훨씬 더 중요하다.
join의 핵심은 저장되는 것도 중요하지만 중복회원검증 로직이 잘 돌아가서 예외가 잘 나오는지도 확인해야 한다.

@Test
    public void 중복_회원_예외(){
        //given
        Member member1=new Member();
        member1.setName("spring");

        Member member2=new Member();
        member2.setName("spring");
        //when
        //then

    }

중복회원을 만들어서 저장해본다.
member1과 member2의 이름을 모두 spring으로 한다.
그 다음 가입을 join을 2번 하는데 첫 번째 가입은 문제가 없지만 두 번째 가입은 이름이 중복되므로 validateDuplicateMemeber에서 걸려서 예외가 발생해야 한다.

  try{
            memberService.join(member2);
            fail();
        }catch (IllegalStateException e){
            assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다");
        }

try-catch문을 사용해서 예외 처리를 해줘도 된다.

("이미 존재하는 회원입니다.1234"로 입력하니 실행 실패가 뜬다.)

NullPointerException을 넣으면 테스트가 실패한다.

try-catch보다 더 좋은 문법을 사용해서 할 수도 있다.

memberService.join(member1);
        assertThrows(IllegalStateException.class, ()->memberService.join(member2));

assertThrows를 사용하는데 로직이 돌아가고 member2를 넣었을 때 예외가 나와야 된다.

memberService.join(member1);
        assertThrows(NullPointerException.class, ()->memberService.join(member2));
        

Ctrl+Alt+v 단축키를 사용해서 아래와 같이 바꿔주고 검증한다.

IllegalStateException e = assertThrows(IllegalStateException.class, () -> memberService.join(member2));


테스트에 성공했다.
전체를 테스트로 돌려도 성공이다.

    @Test
    void 회원가입() {
        //given
        Member member=new Member();
        member.setName("spring");

        //when
        Long saveId=memberService.join(member);

        //then
        Member findMember=memberService.findOne(saveId).get();
        Assertions.assertThat(member.getName()).isEqualTo(findMember.getName());

    }

"hello"를 "spring으로 바꿔주면
테스트에 실패하는데 db에 값이 계속 누적되고 있기 때문에 spring은 이미 가입된 값으로 나온다. 그래서 클리어를 해줘야 한다.

MemoryMemberRepository memberRepository = new MemoryMemberRepository();

    @AfterEach
    public void afterEach() {
        memberRepository.clearStore();
    }

위의 코드를 추가하면 한번 실행되고 나서 db의 값을 모두 날려준다.

현재 MemberMemoryRepository와 MemberMemoryRepositoryTest에서 만든 repository는 서로 다른 인스턴스이다. 그렇기 때문에 같은 인스턴스를 쓰도록 설정하려면 바꿀 부분이 있다.

public class MemberService {
 private final MemberRepository memberRepository;
 public MemberService(MemberRepository memberRepository) {
 this.memberRepository = memberRepository;
 }
 ...
}

이런식으로 MemberService를 직접 생성하는 것이 아니라 외부에서 넣어주도록 바꿔주면 된다.

class MemberServiceTest {


    MemberService memberService;
    MemoryMemberRepository memberRepository;
    
    @BeforeEach
    public void beforeEach(){
        memberRepository=new MemoryMemberRepository();
        memberService=new MemberService(memberRepository);
    }
 }
 ...
 

MemberService를 생성할 때 MemberRepositor를 직접 넣어주려면 BeforeEach를 추가해서 동작하기 전에 넣어주면 된다.

이런식으로 같은 MemoryMemeberRepository가 사용되도록 하는 것을 MemberService입장에서 보면 외부에서 MemberRepository를 넣어주기 때문에 의존성 주입, DI(Dependency Injection)라고 한다.

DI는 의존 관계를 외부에서 결정하여 주입한다는 의미를 가진다. 예를 들어 A클래스와 B클래스가 있을 때 B클래스의 변경이 A클래스에 영향을 미치면 A와 B의 관계는 의존 관계를 가지고 있다고 본다.
DI를 통해 모듈간의 결합도를 낮출 수 있고 유연성을 높일 수 있다.

References

스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술 https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%9E%85%EB%AC%B8-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8

0개의 댓글