Backend/Spring Framework

[Spring Boot] private 메소드 테스트 하기 (with. Kotest)

mopil 2022. 12. 26. 15:58
반응형

서비스 레이어 단위 테스트를 할 때 private 메소드를 테스트 하는 방법에 대해 공유하고자 한다.

 

# 테스트 할 메소드

private fun String.toSort(): Sort {
    return if (this == "DATE") {
        Sort.by(Sort.Direction.DESC, "modifiedAt")
    } else {
        Sort.by(Sort.Direction.DESC, "likeCount")
    }
}

문자열 확장함수로 정의된 toSort() 메소드는 정렬 기준을 문자열로 DATE 이면, modifiedAt 기준 내림차순, LIKE이면 likeCount 기준 내림차순으로 정렬하는 Sort 객체를 반환하는 메소드이다.

 

# private 메소드 자체 테스트

@Test
fun `(private) toSort() 최신순 정렬 성공`() {
    // given
    val toSort: Method = boastService.javaClass.getDeclaredMethod("toSort", String::class.java)
        .apply { isAccessible = true }
    val sortType = "DATE"

    // when
    val sort = toSort.invoke(boastService, sortType) as Sort

    // then
    sort.getOrderFor("modifiedAt")?.direction shouldBe Sort.Direction.DESC
}

Java 리플렉션을 활용한 코드이다.

getDeclaredMethod 메소드를 통해서 함수이름과 파라미터 타입을 전달한다.

그러면 Method 타입의 객체를 리턴 받는데, isAccessible = true 를 통해 외부에서도 접근할 수 있게 설정한다.

그리고 이를 나중에 invoke를 통해서 호출하면 된다.

Kotlin의 고차함수 apply를 활용하면 보다 깔끔하게 코드를 작성할 수 있다. 

 

# private 메소드 stubbing

mocking을 통해서 비즈니스 로직을 수행하는 함수를 테스트 할 때, private 메소드를 stubbing 해야하는 경우도 있다.

이럴경우 리플렉션 말고 mockk에서 지원하는 spyk를 활용하면 된다.

// private 메소드 테스트 할라면 spyk로 모킹 해야 함
private val inquiryService: InquiryService = spyk(
    InquiryService(userService, inquiryRepository),
    recordPrivateCalls = true // private 메소드 호출 허용
)

spyk를 통해 해당 서비스를 생성하면서 recordPrivateCalls = true 설정을 해준다.

@BeforeAll
fun stub() {
    // inquiryService에서 getInquiry private 메소드가 호출되는 경우를 stubbing
    every { inquiryService["getInquiry"](0L) } returns testInquiry
}

stubbing은 인덱스 접근 표현방식을 통해 위와 같이 작성하면 된다.

반응형