개발/Spring

spring에서 private 테스트는 어떻게 할까? (feat. ReflectionTestUtils, kotlin)

보리ing 2022. 3. 27. 23:38
ReflectionTestUtils.getField(target(Object or class), fieldName) as fieldType

테스트코드를 짜다보면 테스트 후 private field가 제대로 바꼈는지 확인하거나 private fun 을 확인하고 싶을때가 있다.

이런경우

spring에 내장되어있는 ReflectionTestUtils 를 사용해서 간단히 테스트를 할 수 있다.

 

예를 위해 만든 클래스니 간단히 형태만 보자

class Number(var number: Int, private var bonus: Int = 3) {

    fun add(addedNumber: Int) {
        number += addedNumber
        addBonus()
    }

    private fun addBonus() {
        if (bonus > 0) {
            number++
            bonus--
            return
        }
        refillBonus(10)
    }

    private fun refillBonus(refilledNumber: Int) {
        bonus = refilledNumber

    }
}

위와 같이 number와 bonus값을 입력받아 숫자를 더할때 보너스가 있다면 1씩 추가되는 Number가 있다.

이때 add가 되고나면 bonus가 정상적으로 깎였는지 알고 싶지만, private라 꺼내어 확인할 수 가 없다.

이런경우

 

ReflectionTestUtils.getField(target(Object or class), fieldName) as fieldType

 

의 형태로 필드를 가져올 수 있다.

 

@Test
fun `getBonusFieldTest`() {
    // given
    val number = Number(10, 5)

    // when
    number.add(1)

    // then
    val bonus = ReflectionTestUtils.getField(number, "bonus") as Int
    assertThat(bonus).isEqualTo(4)
}

 

또한, addBonus와 refillBonus와 같이 private 메서드를 테스트하고 싶다면

ReflectionTestUtils.invokeMethod<Type>(target, methodName, parameters(args))

와 같은 형태로 private 메서드를 실행시켜 테스트를 할 수 있다.

method네임 다음부터는 args형태의 파라미터이니, 파라미터 수만큼 순서대로 입력하면 된다.

 

@Test
fun `privateAddBonusTest`() {
    // given
    val number = Number(10, 1)

    // when
    ReflectionTestUtils.invokeMethod<Number>(number, "addBonus")

    // then
    val bonus = ReflectionTestUtils.getField(number, "bonus") as Int
    assertThat(bonus).isEqualTo(0)
}


@Test
fun `privateRefillBonusTest`() {
    // given
    val number = Number(10, 1)

    // when
    ReflectionTestUtils.invokeMethod<Number>(number, "refillBonus",10)

    // then
    val bonus = ReflectionTestUtils.getField(number, "bonus") as Int
    assertThat(bonus).isEqualTo(10)
}