liminfo

Mockito 레퍼런스

Java Mockito 테스트 프레임워크 API 및 사용법 가이드

25개 결과

Mockito 레퍼런스 소개

Mockito 레퍼런스는 단위 테스트와 통합 테스트에서 가장 널리 사용되는 Java 모킹 프레임워크 Mockito의 완전한 검색형 치트 시트입니다. 모의객체(mock(), spy(), reset(), 프레임워크 리스너), 스텁(when().thenReturn(), thenThrow(), thenAnswer(), doReturn(), 연쇄 스텁), 검증(verify(), times()/never()/atLeast(), verifyNoMoreInteractions(), InOrder, ArgumentCaptor), 인자 매처(any(), eq(), argThat(), isNull()/isNotNull()), 어노테이션(@Mock, @InjectMocks, @Spy, @Captor), 고급 기능(lenient(), mockStatic(), mockConstruction()) 여섯 가지 카테고리로 구성됩니다.

Java 백엔드 엔지니어, Spring Boot 개발자, Android 개발자들은 실행 중인 데이터베이스나 외부 서비스 없이 서비스 레이어, 컨트롤러, 레포지토리를 단위 테스트할 때 Mockito를 광범위하게 사용합니다. Mockito는 실제 의존성을 제어된 값을 반환하거나, 특정 예외를 던지거나, 나중에 검증할 수 있도록 상호작용을 기록하는 모의 객체로 대체함으로써 테스트 격리를 가능하게 합니다. @InjectMocks 어노테이션은 모의 객체를 테스트 대상 클래스에 자동으로 주입하여 보일러플레이트 설정 코드를 줄여줍니다.

레퍼런스의 각 항목은 정확한 Mockito 메서드 또는 어노테이션 문법, 동작 설명, 그리고 ArgumentCaptor로 레포지토리 save() 호출 검증, argThat()을 사용한 커스텀 어설션 로직, 연속 호출을 위한 thenReturn() 체이닝, Mockito 3.4에서 도입된 mockStatic()을 이용한 정적 유틸리티 메서드 모킹 등 일반적인 패턴을 다루는 실제 Java 코드 예제를 제공합니다.

주요 기능

  • 6개 카테고리: 모의객체, 스텁, 검증, 인자매처, 어노테이션, 고급
  • 모든 스텁 변형: thenReturn(), thenThrow(), 동적 응답을 위한 thenAnswer(), spy용 doReturn()
  • 검증 모드: times(n), never(), atLeast(n), atMost(n), verifyNoMoreInteractions()
  • 여러 모의 객체에 걸친 메서드 호출 순서 검증을 위한 InOrder
  • 모의 메서드에 전달된 실제 객체를 캡처하여 검증하는 ArgumentCaptor
  • JUnit 5 어노테이션: @Mock, @InjectMocks, @Spy, @Captor(@ExtendWith(MockitoExtension.class)와 함께)
  • 고급: 정적 메서드용 mockStatic()과 생성자 모킹용 mockConstruction() (Mockito 3.4+)
  • 인자 매처: any(), anyString(), eq(), 람다 조건자를 사용하는 argThat(), isNull()/isNotNull()

자주 묻는 질문

Mockito에서 mock()과 spy()의 차이는 무엇인가요?

mock(Class)는 순수 모의 객체를 생성하며 모든 메서드는 스텁되지 않으면 기본값(null, 0, false, 빈 리스트)을 반환합니다. spy(object)는 실제 객체 인스턴스를 감싸며, 스텁되지 않은 메서드는 실제 구현으로 위임되고 스텁된 메서드는 설정된 값을 반환합니다. 대부분의 메서드에서 실제 동작이 필요하지만 일부만 재정의하거나 검증하려는 경우 spy()를 사용하세요.

when().thenReturn()으로 메서드를 스텁하는 방법은?

when(mockObject.method(args)).thenReturn(value) 패턴을 사용합니다. 예: when(mockUserService.findById(1L)).thenReturn(new User("Kim")). 이후 mockUserService.findById(1L)를 호출하면 User("Kim") 객체가 반환됩니다. void 메서드나 spy 사용 시에는 스텁 설정 중 실제 메서드 호출을 피하기 위해 doReturn(value).when(mock).method() 를 사용하세요.

ArgumentCaptor란 무엇이고 언제 사용해야 하나요?

ArgumentCaptor는 모의 메서드에 전달된 실제 인자를 캡처하여 그 속성을 검증할 수 있게 해줍니다. 테스트 대상 코드 내부에서 인자가 생성되어 동등한 인스턴스를 verify()에 전달하기 어려울 때 사용합니다. 예: ArgumentCaptor<User> captor = ArgumentCaptor.forClass(User.class); verify(mockRepo).save(captor.capture()); assertEquals("Kim", captor.getValue().getName());

@InjectMocks는 무엇을 하고 어떻게 동작하나요?

@InjectMocks는 어노테이션이 붙은 클래스의 인스턴스를 생성하고 모든 @Mock 및 @Spy 필드를 생성자 주입, 세터 주입, 필드 주입 순서로 주입하도록 Mockito에 지시합니다. new UserService(mockRepo, mockEmailService)를 수동으로 호출하는 보일러플레이트를 없애줍니다. 테스트 클래스의 @ExtendWith(MockitoExtension.class) 어노테이션이 주입을 트리거합니다.

메서드가 특정 횟수만큼 호출되었는지 어떻게 검증하나요?

verify(mock, times(n)).method()를 사용합니다. 예: verify(emailService, times(2)).sendEmail(any()). 그 외에 verify(mock, never()).method()는 메서드가 호출되지 않았음을 검증하고, verify(mock, atLeast(1)).method()는 최소 한 번 이상 호출되었음을, verify(mock, atMost(3)).method()는 최대 세 번까지 호출되었음을 검증합니다.

verify()와 verifyNoMoreInteractions()의 차이는 무엇인가요?

verify()는 특정 메서드가 특정 인자로 호출되었는지 확인합니다. verifyNoMoreInteractions(mock)는 이미 검증한 호출 외에 다른 메서드 호출이 없었는지 확인합니다. 테스트 대상 코드가 예상치 못한 부작용을 일으키지 않는지 확인할 때 사용합니다 — 예를 들어, 조건이 거짓일 때 이메일을 보내지 않았음을 확인하는 경우.

정적 메서드 테스트에 mockStatic()은 어떻게 동작하나요?

mockStatic()(Mockito 3.4부터 사용 가능)은 try-with-resources 블록 안에서 정적 메서드를 위한 범위가 지정된 모의 객체를 생성합니다: try (MockedStatic<Utils> mocked = mockStatic(Utils.class)) { mocked.when(Utils::now).thenReturn(fixedTime); /* 테스트 코드 */ }. 정적 모의 객체는 try 블록 이후 자동으로 닫히고 초기화되어 테스트 오염을 방지합니다.

argThat()은 eq()나 any() 대신 언제 사용하나요?

argThat(조건자)는 eq()로 표현할 수 없는 복잡한 조건을 검증해야 할 때 사용합니다 — 예를 들어 save()에 전달된 User 객체의 이름이 "Kim"이고 나이가 18 초과인지 검증. argThat()은 람다를 받습니다: verify(mock).save(argThat(user -> user.getName().equals("Kim") && user.getAge() > 18)). 인자가 중요하지 않을 때는 any(), 정확한 동등성이 필요할 때는 eq(value)를 사용하세요.