Java @Mock、@MockBean 和 Mockito.mock() 的区别
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/44200720/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Difference between @Mock, @MockBean and Mockito.mock()
提问by Doug
When creating tests and mocking dependencies, what is the difference between these three approaches?
在创建测试和模拟依赖时,这三种方法有什么区别?
@MockBean:
@MockBean MyService myservice;
@Mock:
@Mock MyService myservice;
Mockito.mock()
MyService myservice = Mockito.mock(MyService.class);
@模拟豆:
@MockBean MyService myservice;
@嘲笑:
@Mock MyService myservice;
Mockito.mock()
MyService myservice = Mockito.mock(MyService.class);
采纳答案by davidxxx
Plain Mockito library
普通 Mockito 库
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.
来自 Mockito 库并且在功能上是等效的。
它们允许模拟类或接口并记录和验证其上的行为。
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 :
请注意,要在测试执行期间启用 Mockito 注释,
MockitoAnnotations.initMocks(this)
必须调用静态方法。
为了避免测试之间的副作用,建议在每次测试执行之前进行:
@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 :
启用 Mockito 注释的另一种方法是@RunWith
通过指定MockitoJUnitRunner
执行此任务的测试类以及其他有用的东西来注释测试类:
@RunWith(org.mockito.runners.MockitoJUnitRunner.class)
public MyClassTest{...}
Spring Boot library wrapping Mockito library
Spring Boot 库包装 Mockito 库
This is indeed a Spring Boot class:
这确实是一个Spring Boot 类:
import org.springframework.boot.test.mock.mockito.MockBean;
...
@MockBean
MyService myservice;
The class is included in the spring-boot-test
library.
该类包含在spring-boot-test
库中。
It allows to add Mockito mocks in a Spring ApplicationContext
.
If a bean, compatible with the declared class exists in the context, it replacesit by the mock.
If it is not the case, it addsthe mock in the context as a bean.
它允许在 Spring 中添加 Mockito 模拟ApplicationContext
。
如果上下文中存在与声明的类兼容的 bean,它将用模拟替换它。
如果不是这种情况,它会将模拟添加到上下文中作为 bean。
Javadoc reference :
Javadoc参考:
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.
可用于向 Spring ApplicationContext 添加模拟的注释。
...
如果上下文中定义的相同类型的任何现有单个 bean 将被模拟替换,如果没有定义现有 bean,则将添加一个新 bean。
When use classic/plain Mockito and when use @MockBean
from Spring Boot ?
何时使用经典/普通 Mockito 以及何时@MockBean
从 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 andyou want also to add or mock one of the container beans : @MockBean
from Spring Boot is the way.
当您编写一个不需要来自 Spring Boot 容器的任何依赖项的测试时,经典/普通 Mockito 是遵循的方法:它速度快并且有利于测试组件的隔离。
如果您的测试需要依赖 Spring Boot 容器,并且您还想添加或模拟容器 bean 之一:@MockBean
来自 Spring Boot 是一种方法。
Typical usage of Spring Boot @MockBean
Spring Boot 的典型用法 @MockBean
As we write a test class annotated with @WebMvcTest
(web test slice).
当我们编写一个用@WebMvcTest
(web test slice)注释的测试类时。
The Spring Boot documentationsummarizes that very well :
Spring Boot 文档很好地总结了这一点:
Often
@WebMvcTest
will be limited to a single controller and used in combination with@MockBean
to provide mock implementations for required collaborators.
通常
@WebMvcTest
将仅限于单个控制器,并结合使用@MockBean
为所需的协作者提供模拟实现。
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"));
}
}
回答by Patrick
At the end its easy to explain. If you just look into the javadocs of the annotations you will see the differents:
最后很容易解释。如果您只查看注释的 javadoc,您会看到不同之处:
@Mock: (org.mockito.Mock
)
@Mock: ( org.mockito.Mock
)
Mark a field as a mock.
- Allows shorthand mock creation.
- Minimizes repetitive mock creation code.
- Makes the test class more readable.
- Makes the verification error easier to read because the field name is used to identify the mock.
将字段标记为模拟。
- 允许速记模拟创建。
- 最大限度地减少重复的模拟创建代码。
- 使测试类更具可读性。
- 使验证错误更易于阅读,因为字段名称用于标识模拟。
@MockBean: (org.springframework.boot.test.mock.mockito.MockBean
)
@MockBean: ( org.springframework.boot.test.mock.mockito.MockBean
)
Annotation that can be used to add mocks to a Spring ApplicationContext. Can be used as a class level annotation or on fields in either
@Configuration
classes, or test classes that are@RunWith
the SpringRunner.Mocks can be registered by type or by bean name. 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
@MockBean
is used on a field, as well as being registered in the application context, the mock will also be injected into the field.
可用于向 Spring ApplicationContext 添加模拟的注释。可用作类级别注释或用于类中的字段
@Configuration
,或@RunWith
作为 SpringRunner 的测试类。Mocks 可以按类型或 bean 名称注册。任何在上下文中定义的相同类型的现有单个 bean 都将被模拟替换,如果没有定义现有 bean,将添加一个新 bean。
当
@MockBean
在字段上使用时,以及在应用程序上下文中注册时,模拟也将被注入到该字段中。
Mockito.mock()
Mockito.mock()
Its just the representation of a
@Mock
.
它只是 a 的表示
@Mock
。