Kotlin

Error Stubbing 하기

mayleaf 2023. 12. 21. 23:29

이 글을 쓰는 목적

이 글은 우리가 일상적으로 사용하던 에러 출력들을 하기 위해서 어떤 함수들이 필요한지를 적어둔 글입니다.

코드를 작성하는 중에는 에러 안에 어떤 내용이 들어가는지 생각하지 않는 경우가 많고, 그냥 구현해버리면 되는 일이기 때문에 넘어가곤 합니다. 이 글을 쓰게 된 것은 코틀린 테스트코드를 작성하다보니, Exception을 넘겨주고 테스트를 하다보니, stubbing을 더 해줘야하는 것을 보고 이런 것들까지 구현해줘야한다는 걸 공유하고 싶어서 작성합니다.

Error Stubbing?

Webclient에서 받은 응답을 상태코드에 따라서 다르게 처리하도록 작업을 진행하고 있었다. 그러던 도중 함수를 분해해서 구현해두었는데, Webclient까지 목킹하는건 내가 원하던 범위 밖이어서 상태코드에 따른 로직들만 점검하는 테스트코드를 작성하려고 했다. 아래와 같이 API를 호출하는 로직이 있다고 하면, 나는 에러가 난 상황에 대해서 비즈니스 로직을 작성한 onDoSomething 코드를 검증하고 싶은 것이다.

    return webClient.post().uri("localhost:8080/example-route")
            .body(
                Mono.just("body"),
                String::class.java
            )
            .retrieve()
            .onStatus(HttpStatusCode::is2xxSuccessful) { clientResponse ->
                logger().info("success! TGIF!")
                clientResponse.bodyToMono()
            }
            .onStatus(HttpStatusCode::is4xxClientError) { clientResponse ->
                onDoSomething(clientResponse, dto)
            }
            .onStatus(HttpStatusCode::is5xxServerError) { clientResponse ->
                onDoSomething(clientResponse, dto)
            }
            .bodyToMono(String::class.java)

그런데 저 인터페이스를 수정하기 위해서는 clientResponse를 넘겨줘야한다. 그렇기 위해서는 아래 코드처럼 clientResponse의 동작을 지정해줘야하는데, ClientResponse를 목으로 만들고 스터빙을 해주면 된다. 여기까지가 //error stubbing이전까지의 코드이다. onDoSomething에서는 clientResponse를 가지고 어떤 작업을 수행하는데, 이때 clientResponse가 bodyToMono를 통해서 반환하는 에러가 만약 안에서 로깅이 되는 로직이 있다면 어떻게 될까?

        every { clientResponse.bodyToMono<Any>() } answers { Mono.just("test_code_") }
        every { clientResponse.bodyToMono<Throwable>() } answers {
            Mono.just(badRequestException)
        }
        every { clientResponse.statusCode() } returns HttpStatus.BAD_REQUEST
        every { clientResponse.createException() } returns Mono.just(badRequestException)
        // error stubbing
        every { badRequestException.responseBodyAsString } returns "responseDoesn'tMatter"
        every { badRequestException.message } returns "Mayleaf studio is the best"
        every { badRequestException.stackTrace } returns arrayOf()
        every { badRequestException.cause } returns null
        every { badRequestException.suppressed } returns null

해당 함수들이 비어있는 상태이기 때문에 아무런 일도 벌어지지 않고 테스트가 왜 안끝나지? 하면서 몇분을 기다리게 될 것이다. 그렇기 때문에 에러를 찍는 코드가 내부에 있다. 있을것이다.하는 상황이라면 에러도 스터빙해줘야하는 상황이 올수 있다.

확인된 부분

1.에러를 찍으려면 저 //errorstubbing 아래에 있는 함수들을 구현해줘야한다.
2.log.error를 사용하면 저 함수들이 호출이 된다.