Image
Testing Codes/MockK

[MockK] verify 사용해 목 객체의 상호 작용 테스트하기

테스트에서 사용할 객체 

테스트에서 사용할 객체는 다음과 같다. 이 객체들에 대해서는 이전 글에서 이미 설명했고 복잡하지 않은 객체이므로, 추가로 설명하지 않는다.

class UserProfileFetcher(
    private val userRepository: UserRepository,
) {
    fun getUserProfileById(id: String): UserProfile {
        return UserProfile(
            id = id,
            name = userRepository.getNameByUserId(id)
        )
    }
}

interface UserRepository {
    fun saveUserName(id: String, userName: String)
    fun getNameByUserId(id: String): String
}

 

Test Doubles에서의 Mock

Test Doubles에서의 Mock은 상호작용을 테스트 할 수 있는 모방 객체를 뜻한다. 즉, 목 객체의 어떤 함수가 호출되었는지도 기록하며 어떤 입력값이 들어왔는지도 기록한다. 

 

MockK의 verify 사용해  목 객체의 상호 작용 테스트하기 

MockK에서 제공하는 목 객체도 테스트 대상 객체와 어떤 상호작용이 일어났는지 기록하는 기능을 제공한다. MockK는 목 객체의 상호작용을 Assert(단언)하기 위해 verify 함수를 지원하며, 다음과 같이 verify함수를 사용할 수 있다.

class UserProfileFetcherTest {
    @Test
    fun verifyTest() {
        // Given
        val userRepository: UserRepository = mockk()
        val userProfileFetcher = UserProfileFetcher(
            userRepository = userRepository
        )
        every { userRepository.getNameByUserId(any()) } returns "TestUser"

        // When
        val result = userProfileFetcher.getUserProfileById("0xffffffff")

        // Then
        verify {
            userRepository.getNameByUserId("0xffffffff")
        }
    }
}

verify의 람다식에는 목 객체의 어떤 함수가 어떤 값으로 호출되었는지가 들어가며, 이를 통해 해당 함수가 호출되었는지 확인하는 테스트를 만들 수 있다. 위 테스트에서는 userProfileFetcher.getUserProfileById("0xffffffff")이 호출되었을 때 userRepository.getNameByUserId("0xffffffff")이 호출되었는지에 대한 테스트를 실행한다. UserProfileFetcher의 getUserProfileById가 호출되면 인자로 설정된 아이디로 UserRepository의 getNameByUserId함수를 호출하므로 이 테스트는 통과할 것이다.

실제로 테스트를 실행해보면 다음과 같이 테스트가 통과했다는 문구가 나온다

그림1. 목 객체의 상호 작용 테스트

 

이번에는 이 테스트가 정말로 단언을 실행하는지 확인하기 위해 verify에 들어가는 함수를 userRepository.getNameByUserId("0xaaaaaaaa")로 바꿔보자. userRepository.getNameByUserId("0xffffffff")이 호출되고 userRepository.getNameByUserId("0xaaaaaaaa")는 호출되지 않으므로, 이 단언은 실패해야 한다. 

class UserProfileFetcherTest {
    @Test
    fun verifyFailTest() {
        // Given
        val userRepository: UserRepository = mockk()
        val userProfileFetcher = UserProfileFetcher(
            userRepository = userRepository
        )
        every { userRepository.getNameByUserId(any()) } returns "TestUser"

        // When
        val result = userProfileFetcher.getUserProfileById("0xffffffff")

        // Then
        verify {
            userRepository.getNameByUserId("0xaaaaaaaa")
        }
    }
}

따라서 테스트를 실행해보면 0xffffffff가 호출되었는데 0xaaaaaaaa 호출을 단언해서 테스트가 실패했다고 나온다.

그림2. verify 실패 테스트

 

이렇게 verify를 사용해 목 객체의 상호작용을 테스트 할 수 있다.

 

정리

이번 글에서는 verify를 사용해 목 객체의 상호작용을 테스트 하는 방법에 대해 알아보았다. 다음 글에서는 verify에 다양한 인자를 넘겨 상호작용을 더욱 깊게 테스트 하는 방법에 대해 알아볼 것이다. 

 

반응형

 

이 글의 저작권은 '조세영의 Kotlin World' 에 있습니다. 글, 이미지 무단 재배포 및 변경을 금지합니다.

 

 

Kotlin, Android, Spring 사용자 오픈 카톡

오셔서 궁금한 점을 질문해보세요!
비밀번호 : kotlin22

open.kakao.com