Mocking a Method in the Same Test Class Using Mockito Spy

1. 개요

모킹은 단위 테스트에서 매우 유용한 기능으로, 우리가 테스트하고자 하는 단일 동작을 분리하는 데 특히 효과적입니다. 이번 튜토리얼에서는 Mockito Spy를 사용하여 동일한 테스트 클래스에서 메소드를 모킹하는 방법을 살펴보겠습니다.

2. 문제 이해하기

단위 테스트는 테스트의 첫 번째 단계이자 버그에 대한 첫 번째 방어선입니다. 그러나 때때로 메소드가 여러 호출로 인해 너무 복잡해지기도 합니다. 특히 레거시 코드에서는 리팩토링의 가능성이 항상 있는 것은 아닙니다. 단위 테스트를 단순화하기 위해, 간단한 예제를 통해 Mockito Spy의 힘을 보여드리겠습니다.

우리 예제에서는 CatTantrum라는 클래스를 소개하겠습니다:

public class CatTantrum {
    public enum CatAction {
        BITE,
        MEOW,
        VOMIT_ON_CARPET,
        EAT_DOGS_FOOD,
        KNOCK_THING_OFF_TABLE
    }

    public enum HumanReaction {
        SCREAM,
        CRY,
        CLEAN,
        PET_ON_HEAD,
        BITE_BACK,
    }

    public HumanReaction whatIsHumanReaction(CatAction action) {
        return switch (action) {
            case MEOW -> HumanReaction.PET_ON_HEAD;
            case VOMIT_ON_CARPET -> HumanReaction.CLEAN;
            case EAT_DOGS_FOOD -> HumanReaction.SCREAM;
            case KNOCK_THING_OFF_TABLE -> HumanReaction.CRY;
            case BITE -> biteCatBack();
        };
    }

    public HumanReaction biteCatBack() {
        // Some logic
        return HumanReaction.BITE_BACK;
    }
}

메소드 whatIsHumanReaction()는 일부 로직과 메소드 biteCatBack()의 호출을 포함하고 있습니다. 우리는 메소드 whatIsHumanReaction()의 단위 테스트에 집중할 것입니다.

3. Mockito Spy를 이용한 해결책

Mockito Spy를 사용하여 단위 테스트를 작성해 보겠습니다:

@Test
public void givenMockMethodHumanReactions_whenCatActionBite_thenHumanReactionsBiteBack() {
    // Given
    CatTantrum catTantrum = new CatTantrum();
    CatTantrum catTantrum1 = Mockito.spy(catTantrum);
    Mockito.doReturn(HumanReaction.BITE_BACK).when(catTantrum1).biteCatBack();

    // When
    HumanReaction humanReaction1 = catTantrum1.whatIsHumanReaction(CatAction.BITE);

    // Then
    assertEquals(humanReaction1, HumanReaction.BITE_BACK);
}

첫 번째 단계는 Mockito.spy(catTantrum)을 사용하여 테스트 객체의 스파이를 만드는 것입니다. 이 줄은 whatIsHumanReaction()에 의해 호출된 메소드 biteCatBack()의 반환 값을 모킹할 수 있게 해줍니다.

특히, 테스트하고자 하는 메소드를 호출할 때, 원본 객체 catTantrum가 아닌 스파이 객체 catTantrum1에서 호출해야 합니다.

Mockito spy는 클래스의 일부 메소드를 직접 사용할 수 있게 해주고 다른 메소드를 스텁할 수 있게 해줍니다. 만약 우리가 모의 객체를 사용했다면 모든 메소드 호출을 스텁해야 했을 것이며, 반면 객체의 실제 인스턴스를 사용했다면 해당 클래스의 어떤 메소드도 모킹할 수 없었을 것입니다.

위의 예제에서 Mockito Spy는 동일한 객체 catTantrum1에서 실제 메소드 whatIsHumanReaction()을 호출하고, 메소드 biteCatBack()의 스텁을 호출할 수 있게 해주었습니다.

4. 결론

이번 기사에서는 동일한 테스트 클래스에서 메소드를 모킹하는 문제를 해결하기 위해 Mockito Spy를 사용하는 방법을 배웠습니다.

우리는 일반적으로 간단하고 하나의 목적을 가진 메소드를 작성하는 것이 더 좋다는 것을 기억해야 합니다. 그러나 그게 불가능한 경우, Mockito Spy를 사용하면 이 복잡성을 우회하는 데 도움이 될 수 있습니다.

예제에 대한 전체 소스 코드는 GitHub에서 확인할 수 있습니다.

원본 출처

You may also like...

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다