본문 바로가기
Spring/Test

파라미터 값을 테스트하는 Mockito ArgumentCaptor

by 흑시바 2024. 10. 1.

ArgumentCaptor는 Mockito 라이브러리에서 제공하는 기능으로, 메서드 호출 시 전달된 인수를 캡처하고 검증하는 데 매우 유용하다. 이를 통해 테스트 중에 메서드가 호출될 때 전달된 인수를 확인할 수 있다.

ArgumentCaptor란?

ArgumentCaptor는 Mockito 라이브러리에서 제공하는 클래스 중 하나로, 메서드 호출 시 전달된 인수를 캡처하여 나중에 검증할 수 있게 해 준다. 이는 특히 메서드 호출 시 전달된 인수가 예상한 대로 전달되었는지 확인하고자 할 때 유용하다. 예를 들어, 특정 메서드가 호출될 때 전달된 객체의 상태나 값을 검증하고 싶을 때 사용할 수 있다.

사용법

1. 의존성 추가

프로젝트에 Mockito 라이브러리를 추가해야 한다. Maven을 사용하는 경우 pom.xml 파일에 다음 의존성을 추가한다.

 

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>4.0.0</version>
    <scope>test</scope>
</dependency>

2. ArgumentCaptor 생성

ArgumentCaptor 객체를 생성한다. 이는 캡처하려는 인수의 타입을 지정해야 한다.

 

ArgumentCaptor<Type> argumentCaptor = ArgumentCaptor.forClass(Type.class);

3. 메서드 호출 시 캡처

Mockito의 verify 메서드를 사용하여 메서드 호출을 검증할 때 capture 메서드를 사용하여 인수를 캡처한다.

 

verify(mockObject).someMethod(argumentCaptor.capture());

4. 캡처된 인수 검증

캡처된 인수를 getValue 메서드를 사용하여 검증한다.

 

Type capturedArgument = argumentCaptor.getValue();
assertEquals(expectedValue, capturedArgument);

예제

다음은 ArgumentCaptor를 사용하여 메서드 호출 시 전달된 인수를 캡처하고 검증하는 예제이다.

 

import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;

public class UserServiceTest {

    @Test
    public void testCreateUser() {
        // UserRepository를 Mock 객체로 생성
        UserRepository mockUserRepository = mock(UserRepository.class);

        // Mock UserRepository를 사용하여 UserService 생성
        UserService userService = new UserService(mockUserRepository);

        // createUser 메서드 호출
        userService.createUser("shiba_holic");

        // save 메서드에 전달된 인수를 캡처
        ArgumentCaptor<User> userCaptor = ArgumentCaptor.forClass(User.class);
        verify(mockUserRepository).save(userCaptor.capture());

        // 캡처된 인수 검증
        User capturedUser = userCaptor.getValue();
        assertEquals("shiba_holic", capturedUser.getUsername());
    }
}

추가적인 사용법

ArgumentCaptor는 단순히 하나의 인수를 캡처하는 것 외에도 다양한 상황에서 유용하게 사용할 수 있다.

 

1. 여러 인수 캡처

메서드가 여러 인수를 받는 경우, 각각의 인수를 캡처할 수 있다.

 

ArgumentCaptor<Type1> captor1 = ArgumentCaptor.forClass(Type1.class);
ArgumentCaptor<Type2> captor2 = ArgumentCaptor.forClass(Type2.class);
verify(mockObject).someMethod(captor1.capture(), captor2.capture());

Type1 capturedArg1 = captor1.getValue();
Type2 capturedArg2 = captor2.getValue();

2. 여러 번 호출된 메서드의 인수 캡처

메서드가 여러 번 호출된 경우, 각 호출 시 전달된 인수를 모두 캡처할 수 있다.

 

ArgumentCaptor<Type> captor = ArgumentCaptor.forClass(Type.class);
verify(mockObject, times(3)).someMethod(captor.capture());

List<Type> allValues = captor.getAllValues();
assertEquals(3, allValues.size());

3. 복잡한 객체 검증

캡처된 객체의 특정 필드나 상태를 검증할 수 있다.

 

ArgumentCaptor<User> userCaptor = ArgumentCaptor.forClass(User.class);
verify(mockUserRepository).save(userCaptor.capture());

User capturedUser = userCaptor.getValue();
assertEquals("john_doe", capturedUser.getUsername());
assertNotNull(capturedUser.getCreatedAt());

 

ArgumentCaptor는 Mockito와 함께 사용하여 메서드 호출 시 전달된 인수를 캡처하고 검증하는 데 매우 유용한 도구이다. 이를 통해 테스트의 정확성을 높이고, 메서드 호출 시 전달된 인수가 예상한 대로 전달되었는지 확인할 수 있다. 다양한 상황에서 ArgumentCaptor를 활용하여 더 정교한 테스트를 작성할 수 있다.

REFERENCE

https://www.baeldung.com/mockito-argumentcaptor

https://site.mockito.org/javadoc/current/org/mockito/ArgumentCaptor.html

댓글