Mocking Void Methods with Mockito

Dev.Hammy·2024년 4월 1일

Mockito_Tutorial

목록 보기
8/21

1. Overview

이 짧은 튜토리얼에서는 Mockito를 사용하여 void 메소드를 mocking하는 데 중점을 둡니다.

Mockito 프레임워크(예: Mockito Verify, Mockito When/Then 및 Mockito의 Mock 메서드)에 초점을 맞춘 다른 기사와 마찬가지로 아래 표시된 MyList 클래스는 테스트 사례의 공동 작업자로 사용됩니다. 이 튜토리얼에 새로운 메소드를 추가하겠습니다:

public class MyList extends AbstractList<String> {
 
    @Override
    public void add(int index, String element) {
        // no-op
    }
}

2. Simple Mocking and Verifying

Void 메소드는 Mockito의 doNothing(), doThrow()doAnswer() 메소드와 함께 사용하여 모의 및 검증을 직관적으로 만들 수 있습니다.

@Test
public void whenAddCalled_thenVerified() {
    MyList myList = mock(MyList.class);
    doNothing().when(myList).add(isA(Integer.class), isA(String.class));
    myList.add(0, "");
 
    verify(myList, times(1)).add(0, "");
}

그러나 doNothing()void 메소드에 대한 Mockito의 기본 동작입니다.
이 버전의 whenAddCalledVerified()는 위와 동일한 작업을 수행합니다.

@Test
void whenAddCalled_thenVerified() {
    MyList myList = mock(MyList.class);
    myList.add(0, "");
 
    verify(myList, times(1)).add(0, "");
}

doThrow()는 예외를 생성합니다.

@Test
void givenNull_whenAddCalled_thenThrowsException() {
    MyList myList = mock(MyList.class);
    
    assertThrows(Exception.class, () -> {
	doThrow().when(myList).add(isA(Integer.class), isNull());
    });

    myList.add(0, null);
}

아래에서 doAnswer()를 다루겠습니다.

3. Argument Capture

doNothing()을 사용하여 기본 동작을 재정의하는 한 가지 이유는 인수를 캡처하기 위한 것입니다. 위의 예에서는 verify() 메서드를 사용하여 add()에 전달된 인수를 확인했습니다.

그러나 인수를 캡처하고 이를 사용하여 추가 작업을 수행해야 할 수도 있습니다. 이 경우 위에서 했던 것처럼 doNothing()을 사용하지만 ArgumentCaptor를 사용합니다.

@Test
void givenArgumentCaptor_whenAddCalled_thenValueCaptured() {
    MyList myList = mock(MyList.class);
    
    ArgumentCaptor<String> valueCapture = ArgumentCaptor.forClass(String.class);
    doNothing().when(myList).add(any(Integer.class), valueCapture.capture());
    
    myList.add(0, "captured");
    
    assertEquals("captured", valueCapture.getValue());
}

4. Answering a Call to Void

메소드는 단순히 값을 추가하거나 설정하는 것보다 더 복잡한 동작을 수행할 수 있습니다. 이러한 상황에서는 Mockito의 Answer을 사용하여 필요한 동작을 추가할 수 있습니다.

@Test
void givenDoAnswer_whenAddCalled_thenAnswered() {
    MyList myList = mock(MyList.class);
    
    doAnswer(invocation -> {
        Object arg0 = invocation.getArgument(0);
        Object arg1 = invocation.getArgument(1);
        
        assertEquals(3, arg0);
        assertEquals("answer me", arg1);
        return null;
    }).when(myList).add(any(Integer.class), any(String.class));
    
    myList.add(3, "answer me");
}

Mockito의 Java 8 기능에서 설명한 대로 Answer와 함께 람다를 사용하여 add()에 대한 사용자 정의 동작을 정의합니다.

5. Partial Mocking

부분적인 모의도 옵션입니다. Mockito의 doCallRealMethod()는 void 메소드에 사용될 수 있습니다:

@Test
void givenDoCallRealMethod_whenAddCalled_thenRealMethodCalled() {
    MyList myList = mock(MyList.class);
    
    doCallRealMethod().when(myList).add(any(Integer.class), any(String.class));
    myList.add(1, "real");
    
    verify(myList, times(1)).add(1, "real");
}

이렇게 하면 실제 메서드를 호출하고 동시에 확인할 수 있습니다.

0개의 댓글