티스토리 뷰

들어가며

  • 테스트 코드를 작성하는 중 mock class에 대하여 verify를 사용할 일이 있었는데 한 메서드에 대해서 여러번 호출을 하고 검증시에 각각의 호출에 대한 Parameter 를 검증하고자 했다. 
  • 아래와 같은 형태의 코드였는데 원하는 결과를 얻을 수가 없었다 ! 
    • mockFunction() 에 의도한 파라미터가 전달되었는지를 확인하고 싶었지만 기본 verify() 메서드로는 검증이 힘든 상황
class MockClass {
    fun mockFunction(param: String) {
        println(param)
    }
}

class SubjectClass(
    private val mockClass: MockClass,
) {
    fun testFunction() {
        mockClass.mockFunction("foo")
        mockClass.mockFunction("bar")
    }
}

class Test{
    @RelaxedMockK
    private lateinit var mockClass: MockClass

    @InjectMockKs
    private lateinit var sut: SubjectClass
    
    @Test
    fun test() {
        //when
        sut.testFunction()

        //then
        //verify 체크시에 모든 호출에 대하여 판단하기 때문에 실패한다 !
        verify(exactly = 1) { mockClass.mockFunction(withArg { expectThat(it) isEqualTo "foo" }) }
        verify(exactly = 1) { mockClass.mockFunction(withArg { expectThat(it) isEqualTo "bar" }) }
    }
}

해결방법

  • 크게 두가지 방법으로 해결이 가능하다.

verifySequence

  • 메서드명을 보면 알 수 있듯이 Scope 내에서 순차적으로 verify를 수행한다는 것이다. 
  • verifySequence() 를 사용하는 형태로 바꿔보자. 
    • 자세한 Document 내용은 이 곳을 참고
@Test
fun test() {
    //when
    sut.testFunction()

    //then
    verifySequence {
        mockClass.mockFunction(withArg { expectThat(it) isEqualTo "foo" })
        mockClass.mockFunction(withArg { expectThat(it) isEqualTo "bar" })
    }
}

 

Capturing

  • Argument 를 CapturingSlot, MutableList에 capture 할 수 있게 지원하는 기능이다. 
    • 자세한 Document 내용은 이 곳을 참고
  • CapturingSlot 은 단일 값에 대한 Capture 를 위해서 쓰이는 것 같아 보이니 MutableList 를 이용하여 바꿔보자.
    • given 단계에 capturing 절차를 추가한다.
@Test
fun test() {
    //given
    val list = mutableListOf<String>()
    every { mockClass.mockFunction(capture(list)) } returns Unit

    //when
    sut.testFunction()

    //then
    expectThat(list) {
        get { contains("foo") }
        get { contains("bar") }
    }
}

 

반응형
댓글