@Mock、@MockBean 和 Mockito.mock() 的区别 [英] Difference between @Mock, @MockBean and Mockito.mock()

查看:111
本文介绍了@Mock、@MockBean 和 Mockito.mock() 的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在创建测试和模拟依赖时,这三种方法有什么区别?

  1. @MockBean:

    @MockBean我的服务我的服务;

  2. @Mock:

    @Mock我的服务我的服务;

  3. Mockito.mock()

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

解决方案

Plain Mockito 库

import org.mockito.Mock;...@嘲笑我的服务我的服务;

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

来自 Mockito 库并且在功能上是等效的.
它们允许模拟类或接口并记录和验证其上的行为.

使用注解的方式更短,所以更可取,通常更受欢迎.

<小时>

请注意,要在测试执行期间启用 Mockito 注释,MockitoAnnotations.initMocks(this) 必须调用静态方法.
为了避免测试之间的副作用,建议在每次测试执行之前进行:

@Before公共无效initMocks(){MockitoAnnotations.initMocks(this);}

启用 Mockito 注释的另一种方法是通过指定执行此任务的 MockitoJUnitRunner 以及其他有用的东西来使用 @RunWith 注释测试类:

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

<小时>

Spring Boot 库包装 Mockito 库

这确实是一个Spring Boot 类:

import org.springframework.boot.test.mock.mockito.MockBean;...@MockBean我的服务我的服务;

该类包含在 spring-boot-test 库中.

它允许在 Spring ApplicationContext 中添加 Mockito 模拟.
如果上下文中存在与声明的类兼容的 bean,它将替换它由模拟.
如果不是这种情况,它会在上下文中添加模拟作为一个 bean.

Javadoc 参考:

<块引用>

可用于向 Spring 添加模拟的注解应用上下文.

...

如果上下文中定义了任何现有的相同类型的单个 bean将被模拟替换,如果没有现有的 bean 被定义一个新的将被添加.

<小时>

何时使用经典/普通 Mockito 以及何时使用 Spring Boot 中的 @MockBean ?

单元测试旨在独立于其他组件测试一个组件,并且单元测试还有一个要求:在执行时间方面尽可能快,因为这些测试可能每天在开发人员机器上执行数十次.

因此,这里有一个简单的指南:

当你编写一个不需要来自 Spring Boot 容器的任何依赖的测试时,经典/普通的 Mockito 是遵循的方法:它速度快并且有利于被测试组件的隔离.
如果您的测试需要依赖 Spring Boot 容器并且您还想添加或模拟容器 bean 之一:@MockBean from Spring Boot 就是这样.><小时>

Spring Boot的典型用法@MockBean

当我们编写一个用 @WebMvcTest(网络测试切片)注释的测试类时.

Spring Boot 文档 总结得很好:

<块引用>

通常 @WebMvcTest 将被限制为单个控制器并用于结合 @MockBean 提供模拟实现所需的合作者.

这是一个例子:

import org.junit.Test;导入 org.junit.runner.RunWith;导入 org.mockito.Mockito;导入 org.springframework.beans.factory.annotation.Autowired;导入 org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;导入 org.springframework.boot.test.mock.mockito.MockBean;导入 org.springframework.http.MediaType;导入 org.springframework.test.context.junit4.SpringRunner;导入 org.springframework.test.web.servlet.MockMvc;导入静态 org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;导入静态 org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;@RunWith(SpringRunner.class)@WebMvcTest(FooController.class)公共类 FooControllerTest {@自动连线私有 MockMvc mvc;@MockBean私人 FooService fooServiceMock;@测试public void testExample() 抛出异常 {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("一二"));}}

When creating tests and mocking dependencies, what is the difference between these three approaches?

  1. @MockBean:

    @MockBean
    MyService myservice;
    

  2. @Mock:

    @Mock
    MyService myservice;
    

  3. Mockito.mock()

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

解决方案

Plain Mockito library

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

and

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

come from the Mockito library and are functionally equivalent.
They allow to mock a class or an interface and to record and verify behaviors on it.

The way using annotation is shorter, so preferable and often preferred.


Note that to enable Mockito annotations during test executions, the MockitoAnnotations.initMocks(this) static method has to be called.
To avoid side effect between tests, it is advised to do it before each test execution :

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

Another way to enable Mockito annotations is annotating the test class with @RunWith by specifying the MockitoJUnitRunner that does this task and also other useful things :

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


Spring Boot library wrapping Mockito library

This is indeed a Spring Boot class:

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

The class is included in the spring-boot-test library.

It allows to add Mockito mocks in a Spring ApplicationContext.
If a bean, compatible with the declared class exists in the context, it replaces it by the mock.
If it is not the case, it adds the mock in the context as a bean.

Javadoc reference :

Annotation that can be used to add mocks to a Spring ApplicationContext.

...

If any existing single bean of the same type defined in the context will be replaced by the mock, if no existing bean is defined a new one will be added.


When use classic/plain Mockito and when use @MockBean from Spring Boot ?

Unit tests are designed to test a component in isolation from other components and unit tests have also a requirement : being as fast as possible in terms of execution time as these tests may be executed each day dozen times on the developer machines.

Consequently, here is a simple guideline :

As you write a test that doesn't need any dependencies from the Spring Boot container, the classic/plain Mockito is the way to follow : it is fast and favors the isolation of the tested component.
If your test needs to rely on the Spring Boot container and you want also to add or mock one of the container beans : @MockBean from Spring Boot is the way.


Typical usage of Spring Boot @MockBean

As we write a test class annotated with @WebMvcTest (web test slice).

The Spring Boot documentation summarizes that very well :

Often @WebMvcTest will be limited to a single controller and used in combination with @MockBean to provide mock implementations for required collaborators.

Here is an example :

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"));
    }

}

这篇关于@Mock、@MockBean 和 Mockito.mock() 的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆