카테고리 없음

[Java] mockito 어노테이션 - 테스트코드 작성(2)

우엥우아앙 2024. 2. 19. 03:25

@Mock

 

  • Mock 객체의 인스턴스 내부는 비어있다. (Null)
  • Mock 객체를 만드는 방법은 다음과 같다.

 

어노테이션 사용

@Mock
List<String> mockedList;

 

직접 선언

List<String> mockedList = mock(List.class);

 

 


@Spy

  • Spy 객체는 기존 인스턴스와 동일하다.
  • 하지만 원하는 부분에 대해서만 stubbing을 할 수 있다.
  • Spy 객체를 만드는 방법은 다음과 같다.

 

어노테이션 사용

@Spy
List<String> spyList;

 

직접 선언

List<String> spyList = Mockito.spy(List.class);

 

 


@Captor

  • 메서드에 전달된 인자를 캡쳐하는 기능을 제공한다.
  • 캡처할 인자의 타입에 해당하는 Captor 객체를 생성해야 한다.
  • Verify 메서드로 메서드의 인자를 캡처할 수 있다.
  • Mock 객체가 주입되어 내부적으로 객체의 메서드가 호출되는 경우에도 인자를 캡쳐할 수 있다.

 

어노테이션 사용

@Captor
final ArgumentCaptor<String> args;

 

직접 선언

ArgumentCaptor<List> listArgumentCaptor = ArgumentCaptor.forClass(List.class);

 

예시

@Captor
final ArgumentCaptor<String> args;

@DisplayName("ArgumentCaptor를 사용하여 메서드 호출에 사용된 인자를 저장하여 검증한다.(호출을 한 번 했을 때)")
@Test
public void useArgumentCaptorOnce() {
    // given
    final List<String> mockList = mock(List.class);

    // when
    mockList.add("first");
    verify(mockList).add(args.capture());

    // then
    Assertions.assertThat(args.getValue()).isEqualTo("first");
}

@InjectMock

  • 해당 객체의 멤버 변수로 존재하는 의존된 다른 객체들이Mock혹은 Spy로 생성된 객체라면 의존성 주입을 해주는 기능을 제공한다.
public class Car {

    private final Name name;

    public Car(Name name) {
        this.name = name;
    }

    public boolean checkCar(String name) {
        return this.name.isEqualsName(name);
    }

}

Name이라는 객체를 컴포지션 관계로 가지고 있는 Car 객체다.

 

public class Name {

    private final String name;

    public Name(String name) {
        this.name = name;
    }

    public boolean isEqualsName(String name) {
        return this.name.equals(name);
    }

}

field로 가지고 있는 name과 파라미터로 받은 name이 같은지 검증하는 메서드를 가지고 있다

 

@Mock
private Name name;

@DisplayName("InjectMocks를 사용하지 않고 Mock 의존성을 주입받는 방법")
@Test
void non_inject_mocks() {
    // given
    final Car car = new Car(name);

    // when
    Mockito.when(car.checkCar("hyundai")).thenReturn(true);

    // then
    Assertions.assertThat(car.checkCar("hyundai")).isTrue();
    Assertions.assertThat(car.checkCar("kia")).isFalse();
}

InjectMocks 어노테이션을 사용하지 않는다면 아래와 같이 Mock 객체를 직접 생성자에 넣어 Mock 객체가 주입된 Car 객체를 만들어야 한다.

 

@Mock
private Name name;

@InjectMocks
private Car car;

@DisplayName("InjectMocks를 사용해서 Mock 의존성을 주입받는 방법")
@Test
void inject_mocks() {
    // when
    Mockito.when(car.checkCar("hyundai")).thenReturn(true);

    // then
    Assertions.assertThat(car.checkCar("hyundai")).isTrue();
    Assertions.assertThat(car.checkCar("kia")).isFalse();
}

InjectMocks 어노테이션을 사용한다면 따로 Car를 생성할 때 의존성을 주입하지 않아도 Mock이나 Spy 객체로 생성된 객체가 있다면 의존성을 주입해 준다.

 

참고 블로그 : https://developer-nyong.tistory.com/33#article-5-4--@injectmock