@Mock, @MockBean 및 Mockito.mock ()의 ​​차이점


147

테스트를 만들고 종속성을 조롱 할 때이 세 가지 접근 방식의 차이점은 무엇입니까?

  1. @MockBean :

    @MockBean
    MyService myservice;
  2. @모조품:

    @Mock
    MyService myservice;
  3. Mockito.mock ()

    MyService myservice = Mockito.mock(MyService.class);

답변:


199

평범한 모키 토 도서관

import org.mockito.Mock;
...
@Mock
MyService myservice;

import org.mockito.Mockito;
...
MyService myservice = Mockito.mock(MyService.class);

Mockito 라이브러리에서 제공되며 기능적으로 동일합니다.
클래스 또는 인터페이스를 조롱하고 해당 동작을 기록하고 확인할 수 있습니다.

주석을 사용하는 방법이 더 짧으므로 선호하는 경우가 많으며 종종 선호됩니다.


테스트 실행 중 Mockito 주석을 사용하려면 MockitoAnnotations.initMocks(this)정적 메소드를 호출해야합니다.
테스트 간의 부작용을 피하려면 각 테스트 실행 전에 수행하는 것이 좋습니다.

@Before 
public void initMocks() {
    MockitoAnnotations.initMocks(this);
}

Mockito 주석을 활성화하는 또 다른 방법 은이 작업을 수행하는 작업과 다른 유용한 작업 @RunWith을 지정하여 테스트 클래스에 주석을 추가하는 MockitoJUnitRunner것입니다.

@RunWith(org.mockito.runners.MockitoJUnitRunner.class)
public MyClassTest{...}

Mockito 라이브러리를 래핑하는 Spring Boot 라이브러리

이것은 실제로 스프링 부트 클래스입니다 .

import org.springframework.boot.test.mock.mockito.MockBean;
...
@MockBean
MyService myservice;

수업은 spring-boot-test도서관에 포함되어 있습니다.

Spring에 Mockito mock을 추가 할 수 있습니다 ApplicationContext.
선언 된 클래스와 호환 가능한 Bean이 컨텍스트에 존재 하면이를 mock으로 대체 합니다.
그렇지 않은 경우 다음을 추가합니다. 컨텍스트에 모의를 Bean으로 합니다.

Javadoc 참조 :

Spring ApplicationContext에 목업을 추가하는 데 사용할 수있는 주석.

...

컨텍스트에 정의 된 동일한 유형의 기존 단일 Bean이 모의로 대체되는 경우 기존 Bean이 정의되지 않은 경우 새 Bean이 추가됩니다.


클래식 / 일반 Mockito를 사용할 때와 @MockBeanSpring Boot에서 사용할 때 ?

단위 테스트는 다른 구성 요소와 분리하여 구성 요소를 테스트하도록 설계되었으며 단위 테스트에는 요구 사항이 있습니다. 이러한 테스트는 개발자 컴퓨터에서 매일 수십 번 실행될 수 있으므로 실행 시간 측면에서 최대한 빠릅니다.

결과적으로 다음은 간단한 지침입니다.

Spring Boot 컨테이너의 종속성이 필요없는 테스트를 작성할 때 클래식 / 일반 Mockito가 따르는 방법입니다. 빠르고 테스트 된 구성 요소의 격리를 선호합니다.
테스트는 봄 부팅 컨테이너에 의존 할 필요가있는 경우 그리고 당신은 또한 추가하거나 컨테이너 콩의 모의 한하려면 : @MockBean봄 부팅에서 방법입니다.


스프링 부트의 일반적인 사용법 @MockBean

우리는 @WebMvcTest(웹 테스트 조각)으로 주석이 달린 테스트 클래스를 작성합니다 .

Spring Boot 문서 는 다음과 같이 요약합니다.

종종 @WebMvcTest단일 컨트롤러로 제한되며 @MockBean필요한 공동 작업자에게 모의 구현을 제공하기 위해 함께 사용됩니다 .

예를 들면 다음과 같습니다.

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@RunWith(SpringRunner.class)
@WebMvcTest(FooController.class)
public class FooControllerTest {

    @Autowired
    private MockMvc mvc;

    @MockBean
    private FooService fooServiceMock;

    @Test
    public void testExample() throws Exception {
         Foo mockedFoo = new Foo("one", "two");

         Mockito.when(fooServiceMock.get(1))
                .thenReturn(mockedFoo);

         mvc.perform(get("foos/1")
            .accept(MediaType.TEXT_PLAIN))
            .andExpect(status().isOk())
            .andExpect(content().string("one two"));
    }

}

4
@MockBean을 사용하면 Bean의 사본이 작성되어 ApplicationContext에 주입됩니까? 아니면 조롱 된 콩의 모든 메소드가 null입니까? 모든 메소드가 null 인 경우 @Mock을 사용하여 할 수있는 것처럼 스텁 할 수 있습니까?
Doug

6
설명 된 바와 같이, @MockBean동일한 유형을 선언하는 Bean이 Spring 구성에 이미 정의되어있는 경우 애플리케이션 컨텍스트에서 Bean을 사용하여 대체합니다. 그리고 주입은 선언 한 클래스에서 수행됩니다 @MockBean.. DI 메커니즘은 다음과 같이 작동합니다. DI 컨텍스트에 객체를 등록한 다음 Spring 컨텍스트에서 참조 된 객체를 특정 클래스에 주입 할 수 있습니다. DI 컨텍스트에는 개체를 주입하지 않습니다.
davidxxx

13

결국 설명하기 쉽다. 주석의 javadoc을 살펴보면 다른 것을 볼 수 있습니다.

@ 모의 : ( org.mockito.Mock)

필드를 모의로 표시하십시오.

  • 속기 모의 제작이 가능합니다.
  • 반복적 인 모의 생성 코드를 최소화합니다.
  • 테스트 클래스를 더 읽기 쉽게 만듭니다.
  • 필드 이름을 사용하여 모의자를 식별하므로 확인 오류를보다 쉽게 ​​읽을 수 있습니다.

@MockBean : ( org.springframework.boot.test.mock.mockito.MockBean)

Spring ApplicationContext에 목업을 추가하는 데 사용할 수있는 주석. 클래스 레벨 주석 또는 클래스의 필드 @Configuration또는 @RunWithSpringRunner 인 테스트 클래스의 필드로 사용할 수 있습니다 .

Mocks는 유형 또는 Bean 이름으로 등록 할 수 있습니다. 컨텍스트에 정의 된 동일한 유형의 기존 단일 Bean은 모의로 대체됩니다. 기존 Bean이 정의되지 않은 경우 새 Bean이 추가됩니다.

하면 @MockBean필드에 사용할뿐만 아니라, 애플리케이션 컨텍스트에 등록되는 것으로, 모의 또한 필드에 주입한다.

Mockito.mock ()

단지의 표현입니다 @Mock.


5
@Mock을 사용하려면 MockitoRunner 또는 initMocks를 수동으로 호출해야합니다.
Florian Schaetz

4
사이의 유일한 차이 @MockBean@Mock하나가에 모의 주입 것 Spring ApplicationContext, 다른 뜻되지는?
Doug

3
@Doug 당신은 그것을 잘 요약했지만 MockBean은 Spring Boot의 일부라는 것을 기억할 필요가 있습니다
경쟁자
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.