[Spring] Spring Layer Test, Mockito

hyng·2022년 1월 5일
0

서비스 단위 테스트를 작성하면서 알게 된 내용을 정리한 글입니다.

1) F.I.R.S.T 단위 테스트 원칙

1. Fast

단위 테스트는 가능한 빨라야 한다.

테스트 실행이 너무 느리다면, 테스트 실행을 꺼리게 된다.

2. Independent

각 테스트는 서로 의존하면 안 된다. 다른 말로 객체의 상태, 메서드, 이전의 상태, 다른 메서드의 결과 등에 의존해서는 안 된다.

-> 하나가 실패할 때 잇달아서 실패하게 되므로 실패의 원인을 찾기가 어려워진다.

단위 테스트는 독립적으로, 어느 순서로 실행해도 항상 성공해야 한다.

예를 들어 UserService는 UserRepository에 의존한다. 만약 이전 테스트와 현재 테스트에서 동일한 Id 값인 이메일이 저장된다면 Id 중복으로 테스트가 실패하게 된다.

@Transactional를 붙이면 실행 후 DB를 롤백 하기 때문에 실패하지 않지만 실패하는 대상이 UserRepository 인지 UserService 인지 모호해진다.

3. Repeatable

단위테스트는 반복 가능해야 한다.

앞선 예시처럼 Id 중복으로 테스트가 실패하면 안 된다.

4. Self-Validating

개발자가 직접 수동으로 확인할 필요 없이, Assert 문 등으로 확인할 수 있어야 한다.

5. Timely

단위 테스트는 테스트하려는 실제 코드를 구현하기 직전에 구현한다.

2) Mockito

1. Mock 객체란?

테스트를 진행할 때 해당 코드 이외의 의존하는 객체를 가짜로 만든 것을 의미한다.

2. Mockito란?

목객체를 만들어주는 프레임워크

3. Mockito를 사용하는 이유?

•테스트 대상을 독립적으로 테스트하기 위함

•실제 객체는 느릴 수 있다(네트워크, 데이터베이스 연결..)

•의존관계에 있는 다른 코드에서 오류가 날수 있음 .. 등등

Service Test

테스트 대상은 ChatRoomService의 save메소드이고 ChatRoomService는 ChatRoomRepository에 의존한다.

여기서 테스트해야 할 부분은 ChatRoomService.save에서 ChatRoomRepository.save가 호출되는지 확인하는 것이다.

@ExtendWith(MockitoExtension.class)
public class ChatRoomServiceTest {
    @InjectMocks
    private ChatRoomService chatRoomService;

    @Mock
    private ChatRoomRepository chatRoomRepository;

    @Test
    void save(){
        //given
        ChatRoom chatRoom = ChatRoom.create("test");
        //when
        chatRoomService.save(chatRoom);
        //then
        verify(chatRoomRepository).save(any());

    }

Spring-boot-starter-test에 이미 Mockito가 포함되어 있어 따로 의존성 추가해주지 않아도 된다.

@ExtendWith(MockitoExtension.class)

JUnit4에서는 @RunWith 애노테이션을 사용한다.

@Mock이 붙어잇는 목객체를 초기화해주고 @InjectMocks이 붙어있는 객체에 자동으로 목객체를 의존 주입해 준다.

MockitoExtension을 사용하려면 아래와 같이 추가해 주어야 한다.

testImplementation 'org.mockito:mockito-junit-jupiter'

@InjectMocks

의존성 주입이 필요한 목객체를 생성한다.

@Mock

목객체를 생성한다.

@verify

메서드의 호출 여부, 횟수 등을 확인한다.

@SpringBootTest대신 @InjectMocks, @Mock, @ExtendWith(MockitoExtension.class)를 사용함으로써 더욱 빠르게 테스트를 실행할 수 있다.
@SpringBootTest는 Ioc 컨테이너에 모든 빈을 등록하고 테스트를 진행하기 때문에 느릴 수밖에 없다.
Mockito 라이브러리를 사용함으로써 의존성을 제거해 독립적으로 테스트가 가능하다.

참고

https://galid1.tistory.com/772
https://velog.io/@devsh/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B6%80%ED%8A%B8-1-Spring-Boot-Repository-and-Service-Layer-Testing
https://dublin-java.tistory.com/49
https://jdm.kr/blog/222
https://mangkyu.tistory.com/145

profile
공부하고 알게 된 내용을 기록하는 블로그

0개의 댓글