티스토리 뷰

1. Mock 테스트를 위한 라이브러리 추가

Mock 테스트를 위하여 gralde에 아래를 추가하였다.

// Mockito
testImplementation("org.mockito.kotlin:mockito-kotlin:4.0.0")
testImplementation("org.mockito:mockito-core:4.0.0")
testImplementation("org.junit.jupiter:junit-jupiter:5.8.2")

 

2. 서비스 레이어 작성

게시물을 작성하는 코드를 작성한다.

@Service
@RequiredArgsConstructor
class DiaryService(
    private val diaryRepository: DiaryRepository
) {

    @Transactional
    fun createDiary(
        user: User,
        request: CreateDiaryRequestDto
    ): CreateDiaryResponseDto {
        val diary = Diary.from(user, FeelStatus.valueOf(request.feel), request.content)
        val result =  diaryRepository.save(diary)
        return CreateDiaryResponseDto(result.id!!, result.content, result.feelStatus)
    }

}

 

3. Mock 테스트

@ExtendWith(MockitoExtension::class)
class DiaryServiceTest {

    @Mock
    lateinit var diaryRepository: DiaryRepository

    @InjectMocks
    lateinit var diaryService: DiaryService

    @Test
    @DisplayName("사용자는 일기를 작성할 수 있다.")
    fun createDiaryTest() {
        // given
        val user = createUser()
        val diary = createDiary(user)

        val savedDiary = Diary(
            feelStatus = diary.feelStatus,
            user = user,
            content = diary.content
        )
        ReflectionTestUtils.setField(savedDiary, "id", 1L)

        val requestDto = CreateDiaryRequestDto(
            feel = diary.feelStatus.toString(),
            content = diary.content
        )

        whenever(diaryRepository.save(any())).thenReturn(savedDiary)

        // when
        val result = diaryService.createDiary(user, requestDto)

        // then
        assertThat(result).isNotNull
        assertThat(result.diaryId).isEqualTo(savedDiary.id)
        assertThat(result.content).isEqualTo(savedDiary.content)
        assertThat(result.feel).isEqualTo(savedDiary.feelStatus)
    }
}

 

JPA Repository의 save()를 스터빙하였으나 그림 1과 같은 오류가 발생한다.

그림1. NPE 발생

 

4. 오류 발생 원인

결론적으로 오류가 발생한 이유는 스터빙할 때 any()를 사용하는 과정에서 패키지에 문제가 있었기 때문이다.

  • org.mockito.kotlin.any : null을 허용하지 않는다.
  • org.mockito.ArgumentMatchers.any : null을 허용한다.
org.mockito.ArgumentMatchers.any
org.mockito.kotlin.any

 

org.mockito.kotlin.any 패키지를 사용하여 스터빙을 한다면 save()에 null을 허용하지 않게 된다. 그러나 실제 테스트 코드에서 null을 매개변수 인자로 사용하게 되면 스터빙 설정을 찾지 못하게 된다. 따라서 다음 오류가 발생하는 것이다.

java.lang.NullPointerException: save(...) must not be null

import org.mockito.kotlin.any

whenever(diaryRepository.save(any())).thenReturn(savedDiary)

 

그렇다면 diary 객체를 스터빙에 사용하면 어떻게 될까? 테스트 코드에서 사용한 diary 객체와 서비스 레이어에서 생성한 diary 객체가 서로 다른 객체이므로 객체가 일치하지 않는 오류가 발생한다.

그림2. 스터빙에 사용된 diary와 실제 코드 호출에 사용된 diary 객체가 서로 다르다.

import org.mockito.kotlin.any

whenever(diaryRepository.save(diary)).thenReturn(savedDiary)

 

5. 오류 해결

결국 스터빙에서 null을 허용하는 org.mockito.ArgumentMatchers.any 패키지를 사용해야 한다.

import org.mockito.ArgumentMatchers.any

whenever(diaryRepository.save(any())).thenReturn(savedDiary)

 

그림3. 테스트 통과

Total
Today
Yesterday
최근에 올라온 글
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30