Mockito를 이용한 테스트 코드 작성

iy·2024년 2월 16일
0

Mock object(가짜 객체)

  • 각 테스트 케이스는 서로 분리되어야 하고 이를 위해서는 각자 객체인 Mock Object를 생성하는 방법을 이용하면 된다.

Controller 클래스의 테스트를 위해서는 Controller, Service, Repository의 테스트가 필요
Service 클래스의 테스트를 위해서는 Service, Repository의 테스트가 필요
Repository 클래스 테스트를 위해서는 Repository 테스트가 필요
-> 각자 객체(Mock Object)로 분리 필요

  • MockRepository
    - 실제 객체와 겉만 같은 객체
    - 동일한 클래스명, 함수명 사용
    • 실제 DB 작업은 이루어지지 X
      • DB 작업 수행하는 것처럼 작업
        • 테스트를 위해 필요한 결과값을 return

Mockito 이용한 테스트 코드 작성

개인 과제인 스케줄 관리 프로그램에 서비스 단 수정 부분의 테스트 코드를 작성해보려고 한다.

이때 이용할 패턴은 given-when-then을 이용해보려고 한다.
given은 준비, when은 실행, then 검증 과정이다.

// 생성할 때 requestDto
@Getter
@AllArgsConstructor
public class CreateRequestDto {
    private String title;
    private String content;
}
// 수정할 때 requestDto
@Getter
public class UpdateScheduleRequest {
    private String title;
    private String content;

    public UpdateScheduleRequest(String title, String content){
        this.title = title;
        this.content =  content;
    }
}
// 조회할 때 responseDto
@Getter
public class ReadResponseDto {
    private Long scheduleId;
    private String title;
    private String content;
    private LocalDateTime createdDate;
    private LocalDateTime modifiedDate;

    public ReadResponseDto(Schedule schedule) {
        this.scheduleId = schedule.getId();
        this.title = schedule.getTitle();
        this.content = schedule.getContent();
        this.createdDate = schedule.getCreatedDate();
        this.modifiedDate = schedule.getModifiedDate();
    }
}
	// 서비스 단
	@Transactional
    public void updateSchedule(User user,UpdateScheduleRequest updateScheduleRequest, Long scheduleId) {
        Schedule schedule = scheduleRepository.findById(scheduleId).orElseThrow(NoSuchElementException::new);
        schedule.update(user, updateScheduleRequest);
    }

수정할 때 Schedule Entity에서 해당 엔티티에 UpdateRequestDto를 이용해 수정하도록 구현

	// Entity 안에 update 메서드
    public void update(User user, UpdateScheduleRequest updateScheduleRequest) {
        this.user = user;
        this.title = updateScheduleRequest.getTitle();
        this.content = updateScheduleRequest.getContent();
    }

이 부분을 Mockito를 이용해서 서비스 단 테스트를 해보겠다.

@ExtendWith(MockitoExtension.class)
class ScheduleServiceTest {

    @Mock
    ScheduleRepository scheduleRepository;

우선 해당 테스트 클래스에 Mockito 사용을 위한 @ExtendWith(MockitoExtension.class)을 붙여준다. 이를 선언해주면 Mock객체를 만들 수 있는데 @Mock을 붙여주면 해당 객체의 모의 객체를 만들어 사용 가능하다.

    @Test
    @DisplayName("스케줄 내용 변경")
    void 스케줄내용변경(){
        //given
        Long scheduleId = 100L;
        
        User user = new User();
        CreateRequestDto createRequestDto = new CreateRequestDto(
                "스케줄 1",
                "카페 가서 친구 만나는 일정"
        );

        UpdateScheduleRequest updateScheduleRequest = new UpdateScheduleRequest(
                "스케줄1",
                "카페 가서 친구 만나려고 했는데 그냥 혼자 책 읽을까?"
        );
        Schedule schedule = new Schedule(user, createRequestDto);
        ScheduleService scheduleService = new ScheduleService(scheduleRepository);
        given(scheduleRepository.findById(scheduleId)).willReturn(Optional.of(schedule));

given은 테스트를 위한 data들을 준비해주는 구간이라고 보면 된다.
createRequestDto를 이용해 Schedule 하나를 생성해 준비한다.
이중 when 단계에서 필요한 UpdateRequestDto도 준비해둔다.

        //when
        scheduleService.updateSchedule(user,updateScheduleRequest,scheduleId);

when 단계에선 실행을 하는데 createRequestDto로 생성된 스케줄을 updateRequestDto의 내용으로 수정한다.

        //then
        ReadResponseDto readResponseDto = new ReadResponseDto(schedule);
        assertEquals("카페 가서 친구 만나려고 했는데 그냥 혼자 책 읽을까?",readResponseDto.getContent(), "예상하는 값과 다릅니다!");
    }

}

then단계에서 이를 검증하는데 이때 assertEquals를 이용한다.
assertEquals(예상값,실행된 값,만약 틀린 결과가 나올 시 보여줄 메세지)
로 작성해주면 된다.
이렇게 검증을 통해 해당 서비스 단의 메서드가 올바른 코드인지 알 수 있다.

  • 예상 값을 올바르게 작성 했을 때
assertEquals("카페 가서 친구 만나려고 했는데 그냥 혼자 책 읽을까?",readResponseDto.getContent(), "예상하는 값과 다릅니다!");

  • 예상 값을 틀리게 작성 했을 때
assertEquals("그냥 혼자 책 읽을까?",readResponseDto.getContent(),"예상하는 값과 다릅니다!");

이렇게 테스트 코드를 작성하면 다른 클래스의 검증 없이도 서비스 단의 검증만 가능하다.
테스트 코드를 여러 상황들을 예측해 작성해보면 앞으로 코드의 오류가 줄어들 것이고 혹시 코드를 변경하고 싶어도 테스트 코드로 변경해 값이 변하지 않는지 확인할 수 있을 거 같다.
앞으로 과제나 프로젝트에서 테스트 코드 작성을 많이 해봐야겠다.
오늘은 서비스 단만 테스트 해봤지만 앞으로 통합 테스트와 컨트롤러 테스트 등을 공부해서 정리해야 겠다.

0개의 댓글