테스트 코드 구현

김태은·2022년 4월 24일
0
post-thumbnail
  1. build.gradle에 코드 추가
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-rest'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'

    runtimeOnly 'com.h2database:h2'

    compileOnly 'org.projectlombok:lombok:1.18.20'
    annotationProcessor 'org.projectlombok:lombok:1.18.20'

    //test에 필요한 코드
    testImplementation('org.springframework.boot:spring-boot-starter-test')
}
  1. 클래스 명 선택 or 클래스 내부에 커서 둔 채로 [ Ctrl + Shift + T ] 누르기
  1. [ Create New Test... ] 클릭해서 생성하기
  2. 테스트 코드 작성하기
    (TodoService 코드가 맞게 구현이 되었는지 확인)
package org.example.service;

import org.example.model.TodoEntity;
import org.example.model.TodoRequest;
import org.example.repository.TodoRepository;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.AdditionalAnswers;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.web.server.ResponseStatusException;

import java.util.Optional;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
class TodoServiceTest {

    @Mock
    private TodoRepository todoRepository;

    @InjectMocks
    private TodoService todoService;

    @Test
    void add() {
        //todoRepository가 save매소드를 호출해서 TodoEntity 값을 받으면 받은 Entity값을 리턴
        when(this.todoRepository.save(any(TodoEntity.class)))
                .then(AdditionalAnswers.returnsFirstArg());

        TodoRequest expected = new TodoRequest();
        expected.setTitle("Test Title");

        TodoEntity actual = this.todoService.add(expected);

        //넣은 값과 실제로 반환되는 값이 일치하는 지 확인
        assertEquals(expected.getTitle(), actual.getTitle());
    }

    @Test
    void searchById() {

        TodoEntity entity = new TodoEntity();
        entity.setId(123L);
        entity.setTitle("TITLE");
        entity.setOrder(0L);
        entity.setCompleted(false);
        //Optinal로 매핑
        Optional<TodoEntity> optional = Optional.of(entity);
        //어떤 값이든 아이디 값이 주어졌을 때, optinal값을 리턴
        given(this.todoRepository.findById(anyLong()))
                .willReturn(optional);

        TodoEntity actual = this.todoService.searchById(123L);

        TodoEntity expected = optional.get();

        assertEquals(expected.getId(), actual.getId());
        assertEquals(expected.getTitle(), actual.getTitle());
        assertEquals(expected.getOrder(), actual.getOrder());
        assertEquals(expected.getCompleted(),actual.getCompleted());
    }

    @Test
    public void searchByIdFailed(){
        given(this.todoRepository.findById(anyLong()))
                .willReturn(Optional.empty());

        assertThrows(ResponseStatusException.class, () ->{
            this.todoService.searchById(123L);
        });
    }
}
  • Mock을 사용하는 이유
  1. 외부시스템에 의존하지 않고 자체 테스트를 실행할 수 있어야 하기 때문에
  2. 실제 데이터 베이스를 사용하게 되면 테스트를 할 때마다 DB의 값이 추가, 삭제가 될 수 있는데, 실제 DB에는 민감한 정보가 많고, 서비스에서 사용하고 있는 정보가 변경되면 안되기 때문에
  • assertEquals함수를 이용하여 예상한 값과 실제 값이 일치하는 지 확인

  • 실행 결과

-> 테스트 통과

0개의 댓글