테스트 코드 작성 시의 에로사항

2024. 2. 24. 19:39SPRING

class MemberServiceTest {

    MemberService memberService = new MemberService();

    void join() {
        // given
        Member member1 = new Member();
        member1.setName("회원가입테스트용1");
        // when
        memberService.join(member1);
        // then
        assertThat(member1.getId()).isEqualTo(1);
    }

    @Test
    void findMembers() {

    }

    @Test
    void findOne() {
        //when
        Member foundMember = memberService.findOne(1L).get();
        //then
        assertThat(foundMember.getName()).isEqualTo("회원가입테스트용1");
    }

    // service 클래스의 테스트 코드를 작성중이다.
    // 문제 : join 으로 객체를 하나 저장했는데, NoSuchElementException 이 발생한다.
    // 원인 :
    // service 객체를 통해 repository에 객체를 저장했다.
    // 그러나, repository가 join()을 사용할 때에 생성되고, 소멸한다..
    // 따라서, findOne() 등을 테스트할 때 새로운 repository를 사용하게 되므로, 비어있는 repository 를 사용하게 된다. 그래서 예외가 터진다.
    // 해결방안 :
    // 1. 본 코드(MemberService class)에서 MemberRepository 멤버 변수를 static으로 선언
    // 장점 : MR이 static 키워드로 인해 Method 영역에 저장되므로, 동일한 repository를 사용해서 다른 테스트들도 수행 가능하다.
    // 단점 :
    // 테스트 하는 데 본래의 코드가 손상되고, 테스트할 때마다 원형을 수정해야하는 번거로움이 발생함.
    // 2. 본 테스트용 클래스에서 join()의 @Test 애노테이션 제거 & @BeforeEach 를 사용하여 다른 테스트 진행 시 join()이 동작되도록 한다.
    // 장점 : 다른 테스트에서 미리 작성된 join() 메서드를 실행 한 후, 본 코드를 이어서 진행하므로, NoSuchElementException 은 발생하지 않는다.
    // 단점 : join() 을 수정할 때마다 @Test, @BeforeEach 를 삭제, 작성 해야한다.
    // 3. DB 사용
    // 장점 : db에 데이터를 저장하게 되므로, 해당 값들이 유지된다.
    // 단점 : 준비하는 데 시간이 오래 걸린다.
}

 

1, 2 의 경우, 테스트할 때 마다 코드의 수정이 불가피하다.

3이 합당해 보인다.

 

4.로 Mock 라이브러리를 사용하는 것도 방법이라는데, Mock는 추후 학습 해보자.

5, repository를 따로 만들어 @BeforeEach 애노테이션을 사용. 생성자 단계에서 repository를 갖도록 하기

/*
MemberService memberService = new MemberService();

// 뭔가 이상한데?
// Service에 있는 MemberRepository 랑 다른 놈일텐데??
MemberRepository memberRepository = new MemoryMemberRepository();
*/
MemberService memberService;
MemberRepository memberRepository;

// 외부에서 repository 를 넣어주자.
// 어떻게?
// 1. repository 를 하나만 만든다.
// 2. 만들어진 repository를 테스트 마다 생성해줌으로써, 테스트가 동일한 결과를 갖게 한다.


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

 

이러한 구조로 하여금 동일한 repository를 갖게 할 수 있었다.

이러한 일련의 동작(repository 생성해 Service에 넣는 동작)을 Dependency Injection이라 한다.

 

자세한 내용은 다음 글에서 더 학습 해보자.

'SPRING' 카테고리의 다른 글

스프링 빈 등록 방법  (0) 2024.02.25
의존 주입  (0) 2024.02.25
웹 개발 방식_API  (0) 2024.02.21
@RequestParam  (0) 2024.02.21
웹 개발 방식_MVC + 템플릿 엔진 방식  (0) 2024.02.21