본문 바로가기
컴퓨터 프로그래밍/Spring

[Spring] Service Test Code 작성

by 한33 2024. 9. 14.

@Transactional
public CommentSaveResponse saveComment(AuthUser authUser, long todoId, CommentSaveRequest commentSaveRequest) {
    User user = User.fromAuthUser(authUser);
    Todo todo = todoRepository.findById(todoId).orElseThrow(() ->
            new InvalidRequestException("Todo not found"));

    if (!managerRepository.existsManagerByUser_IdAndTodo_id(authUser.getId(), todo.getId())) {
        throw new InvalidRequestException("해당 댓글의 일정에 등록된 담당자가 아닙니다.");
    }



    Comment newComment = new Comment(
            commentSaveRequest.getContents(),
            user,
            todo
    );

    Comment savedComment = commentRepository.save(newComment);

    return new CommentSaveResponse(
            savedComment.getId(),
            savedComment.getContents(),
            new UserResponse(user.getId(), user.getEmail())
    );
}

 

댓글을 저장하는 Service Test Code 를 작성해보려고 한다.

 

@ExtendWith(MockitoExtension.class)
class CommentServiceTest {

    @Mock
    private CommentRepository commentRepository;
    @Mock
    private TodoRepository todoRepository;
    @InjectMocks
    private CommentService commentService;
@ExtendWith(MockitoExtension.class)

 

먼저 위 코드를 클래스 위에 붙여주면서 Mockito 를 사용하기 위한 준비를 해준다.

 

@Mock
private CommentRepository commentRepository;
@Mock
private TodoRepository todoRepository;

 

가짜 객체들을 만들어주고

@InjectMocks
private CommentService commentService;

 

실제 사용해야하는 CommentService 는 InjectMocks 로 선언해준다.

public CommentSaveResponse saveComment(AuthUser authUser, long todoId, CommentSaveRequest commentSaveRequest) {

 

실제 코드에서 saveComment 코드로 들어가는 매개변수가 authUser, todoId, commentSaveRequest 가 필요하다.

 

// given
long todoId = 1;
CommentSaveRequest request = new CommentSaveRequest("contents");
AuthUser authUser = new AuthUser(1L, "email", UserRole.USER);
User user = User.fromAuthUser(authUser);
Todo todo = new Todo("title", "title", "weather", user);
ReflectionTestUtils.setField(todo, "id", todoId);
Comment comment = new Comment(request.getContents(), user, todo);

 

AuthUser authUser = new AuthUser(1L, "email", UserRole.USER);
User user = User.fromAuthUser(authUser);

 

우선 authUser 의 Dummy Data 를 만들어줬다.

long todoId = 1;
Todo todo = new Todo("title", "title", "weather", user);
ReflectionTestUtils.setField(todo, "id", todoId);

 

todoId 를 선언하고 하나의 todo 객체를 만들어서 id 를 할당해줬다.

 

기존에는 id 가 없는 todo 객체였다면 todoId 를 넣어줌으로써 데이터베이스에 저장된 형태로 id 가 들어가있는 todo객체가 되었다.

CommentSaveRequest request = new CommentSaveRequest("contents");

 

입력하게되는 CommentSaveRequest 를 request 라는 이름으로 만들어주고

Comment comment = new Comment(request.getContents(), user, todo);

 

위에서 만든 given 들을 토대로 Comment 객체를 하나 만들어주었다.

 

User user = User.fromAuthUser(authUser);
Todo todo = todoRepository.findById(todoId).orElseThrow(() ->
        new InvalidRequestException("Todo not found"));

if (!managerRepository.existsManagerByUser_IdAndTodo_id(authUser.getId(), todo.getId())) {
    throw new InvalidRequestException("해당 댓글의 일정에 등록된 담당자가 아닙니다.");
}

 

saveComment 의 위 코드를 이제 테스트코드에서 구현하려한다.

 

given(todoRepository.findById(anyLong())).willReturn(Optional.of(todo));
given(commentRepository.save(any())).willReturn(comment);
given(managerRepository.existsManagerByUser_IdAndTodo_id(anyLong(), anyLong())).willReturn(true); // 담당자 존재

 

todoRepository.findById 가 실행되면 todo 객체 하나를 무조건 반환시키게 하고,

commentRepository.save 가 실행되면 무엇이 매개변수로 들어가든 comment 가 나오게 하는 식으로

Mock 을 이용한 방법을 사용한다.

 

CommentSaveResponse result = commentService.saveComment(authUser, todoId, request);

 

given 이 준비가 다 끝났으니 saveComment 의 반환값 CommentSaveResponse 의 꼴로 필요한 매개변수를 넣어서 테스트를 해줬다.

 

assertNotNull(result);

 

result 값이 Null 이 아닌지 then 단계에서 체크해주었다.

 

Test 전체 코드

@Test
public void comment를_정상적으로_등록한다() {
    // given
    long todoId = 1;
    CommentSaveRequest request = new CommentSaveRequest("contents");
    AuthUser authUser = new AuthUser(1L, "email", UserRole.USER);
    User user = User.fromAuthUser(authUser);
    Todo todo = new Todo("title", "contents", "weather", user);
    ReflectionTestUtils.setField(todo, "id", todoId);
    Comment comment = new Comment(request.getContents(), user, todo);

    given(todoRepository.findById(anyLong())).willReturn(Optional.of(todo));
    given(commentRepository.save(any())).willReturn(comment);
    given(managerRepository.existsManagerByUser_IdAndTodo_id(anyLong(), anyLong())).willReturn(true); // 담당자 존재
    // when
    CommentSaveResponse result = commentService.saveComment(authUser, todoId, request);

    // then
    assertNotNull(result);
}

페이지네이션 된 일정 목록 조회

@Test
void 일정목록_조회() {
    // given
    int page = 1;
    int size = 10;
    Pageable pageable = PageRequest.of(page - 1, size);
    AuthUser authUser = new AuthUser(1L, "email", UserRole.USER);
    User user = User.fromAuthUser(authUser);

    Todo todo1 = new Todo("title", "contents", "weather", user);
    Todo todo2 = new Todo("title", "contents", "weather", user);

    Page<Todo> todoPage = new PageImpl<>(List.of(todo1, todo2), pageable, 2);

    given(todoRepository.findAllByOrderByModifiedAtDesc(pageable)).willReturn(todoPage);
    // when

    Page<TodoResponse> result = todoService.getTodos(page, size);
    // then
    assertNotNull(result);
}

 

일정 단건 조회

@Test
void 일정_조회() {
    // given
    long todoId = 1L;
    AuthUser authUser = new AuthUser(1L, "email", UserRole.USER);
    User user = User.fromAuthUser(authUser);
    Todo todo = new Todo("title", "contents", "weather", user);
    ReflectionTestUtils.setField(todo, "id", todoId);

    given(todoRepository.findByIdWithUser(todoId)).willReturn(Optional.of(todo));

    // when
    TodoResponse todoResponse = todoService.getTodo(todoId);
    // then
    assertNotNull(todoResponse);
    assertEquals(1, todoResponse.getId());
    assertEquals("title", todoResponse.getTitle());
    assertEquals("contents", todoResponse.getContents());
    assertEquals("weather", todoResponse.getWeather());
    assertEquals(user.getId(), todoResponse.getUser().getId());

}

 

담당자 삭제

@Test
void manager_담당자_삭제() {
    // given
    // 유저 생성
    given(userRepository.findById(anyLong())).willReturn(Optional.of(CommonDataSetting.getUserSuccessRegister()));
    // 일정 생성
    given(todoRepository.findById(anyLong())).willReturn(Optional.of(CommonDataSetting.getTodoSuccessRegister()));
    // 담당자 유저 생성
    given(managerRepository.findById(anyLong())).willReturn(Optional.of(CommonDataSetting.getManagerSuccessRegister()));

    doNothing().when(managerRepository).delete(any(Manager.class));
    // when

    managerService.deleteManager(
            CommonDataSetting.getUserSuccessRegister().getId(),
            CommonDataSetting.getTodoSuccessRegister().getId(),
            CommonDataSetting.getManagerSuccessRegister().getId());

    //then
    verify(managerRepository, times(1)).delete(any(Manager.class));
}

'컴퓨터 프로그래밍 > Spring' 카테고리의 다른 글

[Spring] Naver Open API  (0) 2024.09.18
[Spring] RestTemplate  (2) 2024.09.17
[Spring] Controller Test Code 작성  (0) 2024.09.14
[Spring] AOP  (0) 2024.09.10
[Spring] 통합 테스트  (1) 2024.09.10