@Mock,@MockBean和Mockito.mock()之间的区别
在创建测试和模拟依赖项时,这三种方法之间有什么区别?
-
@MockBean:
@MockBean MyService myservice;
-
@Mock:
@Mock MyService myservice;
-
Mockito.mock()
MyService myservice = Mockito.mock(MyService.class);
在创建测试和模拟依赖项时,这三种方法之间有什么区别?
@MockBean:
@MockBean
MyService myservice;
@Mock:
@Mock
MyService myservice;
Mockito.mock()
MyService myservice = Mockito.mock(MyService.class);
普莱恩莫基托图书馆
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{...}
弹簧靴库包装莫基托库
这确实是一个Spring Boot类:
import org.springframework.boot.test.mock.mockito.MockBean;
...
@MockBean
MyService myservice;
该类包含在库中。spring-boot-test
它允许在春天添加Mockito模拟。
如果上下文中存在与声明的类兼容的 Bean,它将用 mock 替换它。
如果不是这种情况,它将模拟作为bean添加到上下文中。ApplicationContext
Javadoc reference :
可用于向 Spring 应用程序上下文添加模拟的注释。
...
如果在上下文中定义的任何相同类型的现有单个 Bean 将被 mock 替换,则如果没有定义现有 Bean,则将添加一个新 Bean。
当使用经典/普通的Mockito和当使用@MockBean
从Spring Boot ?
单元测试旨在将组件与其他组件隔离,单元测试也有一个要求:在执行时间方面尽可能快,因为这些测试每天可以在开发人员计算机上执行数十次。
因此,这里有一个简单的指导方针:
当你编写一个不需要来自Spring Boot容器的任何依赖项的测试时,经典/普通的Mockito是遵循的方式:它速度很快,有利于测试组件的隔离。
如果你的测试需要依赖于Spring Boot容器,并且你还想添加或模拟一个容器bean:从Spring Boot是方法。@MockBean
弹簧靴@MockBean
的典型用法
当我们编写一个带注释的测试类时(Web 测试片)。@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"));
}
}
最后,它很容易解释。如果您只查看注释的javadocs,您将看到差异:
@Mock:(org.mockito.Mock
)
将字段标记为模拟。
- 允许创建速记模拟。
- 最大限度地减少重复的模拟创建代码。
- 使测试类更具可读性。
- 使验证错误更易于阅读,因为字段名称用于标识模拟。
@MockBean:(org.springframework.boot.test.mock.mockito.MockBean
)
可用于向 Spring 应用程序上下文添加模拟的注释。可以用作类级注释,也可以在任一类中的字段上使用,也可以用作作为 SpringRunner 的测试类。
@Configuration
@RunWith
可以按类型或 Bean 名称注册模拟。在上下文中定义的任何相同类型的现有单个 Bean 都将被 mock 替换,如果没有定义现有 Bean,则将添加一个新 Bean。
当在字段上使用以及在应用程序上下文中注册时,模拟也将注入到字段中。
@MockBean
Mockito.mock()
它只是一个.
@Mock