在创建测试和模拟依赖关系时,这三种方法之间有什么区别?
@MockBean: @MockBean 我的服务我的服务; @Mock: @Mock 我的服务我的服务; Mockito.mock() MyService myservice = Mockito.mock(MyService.class);
在创建测试和模拟依赖关系时,这三种方法之间有什么区别?
@MockBean: @MockBean 我的服务我的服务; @Mock: @Mock 我的服务我的服务; Mockito.mock() MyService myservice = Mockito.mock(MyService.class);
当前回答
普通Mockito库
import org.mockito.Mock;
...
@Mock
MyService myservice;
and
import org.mockito.Mockito;
...
MyService myservice = Mockito.mock(MyService.class);
它们来自Mockito库,并且在功能上是等价的。 它们允许模拟类或接口,并记录和验证其中的行为。
使用注释的方式更短,因此更可取,也经常是首选。
注意,要在测试执行期间启用Mockito注释,可以使用 必须调用mokitoannotations . initmocks(此)静态方法。 为避免测试之间的副作用,建议在每次测试执行之前执行:
@Before
public void initMocks() {
MockitoAnnotations.initMocks(this);
}
另一种启用Mockito注释的方法是通过指定执行此任务的MockitoJUnitRunner和其他有用的事情来使用@RunWith注释测试类:
@RunWith(org.mockito.runners.MockitoJUnitRunner.class)
public MyClassTest{...}
Spring Boot库包装Mockito库
这确实是一个Spring Boot类:
import org.springframework.boot.test.mock.mockito.MockBean;
...
@MockBean
MyService myservice;
该类包含在spring-boot-test库中。
它允许在Spring ApplicationContext中添加Mockito mock。 如果上下文中存在与声明的类兼容的bean,则用mock替换它。 如果不是这样,它将mock作为bean添加到上下文中。
Javadoc参考:
可用于向Spring添加模拟的注释 ApplicationContext。 ... 上下文中定义的任何相同类型的现有单个bean 将被mock取代,如果没有现有的bean被定义为一个新的 将被添加。
什么时候使用经典/普通Mockito,什么时候从Spring Boot使用@MockBean ?
单元测试的设计目的是在组件与其他组件隔离的情况下测试组件,单元测试也有一个要求:在执行时间方面尽可能快,因为这些测试可能每天在开发人员机器上执行十几次。
因此,这里有一个简单的指导方针:
当您编写一个不需要来自Spring Boot容器的任何依赖项的测试时,经典/普通Mockito是遵循的方法:它速度快,有利于测试组件的隔离。 如果您的测试需要依赖Spring Boot容器,并且您还想添加或模拟其中一个容器bean:来自Spring Boot的@MockBean是一种方法。
Spring Boot @MockBean的典型用法
当我们编写带有@WebMvcTest (web测试片)注释的测试类时。
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)
将一个字段标记为mock。
允许简化模拟创建。 最小化重复的模拟创建代码。 使测试类更具可读性。 使验证错误更容易阅读,因为字段名用于标识模拟。
@MockBean: (org.springframework.boot.test.mock.mockito.MockBean)
可用于向Spring ApplicationContext添加模拟的注释。可以用作类级注释,也可以用于@Configuration类或@RunWith springgrunner的测试类中的字段。
mock可以按类型或bean名注册。任何在上下文中定义的相同类型的现有单个bean都将被mock替换,如果没有定义现有bean,则将添加一个新的bean。
当在字段上使用@MockBean并在应用程序上下文中注册时,mock也将被注入到字段中。
Mockito.mock()
它只是一个@Mock的表示。
普通Mockito库
import org.mockito.Mock;
...
@Mock
MyService myservice;
and
import org.mockito.Mockito;
...
MyService myservice = Mockito.mock(MyService.class);
它们来自Mockito库,并且在功能上是等价的。 它们允许模拟类或接口,并记录和验证其中的行为。
使用注释的方式更短,因此更可取,也经常是首选。
注意,要在测试执行期间启用Mockito注释,可以使用 必须调用mokitoannotations . initmocks(此)静态方法。 为避免测试之间的副作用,建议在每次测试执行之前执行:
@Before
public void initMocks() {
MockitoAnnotations.initMocks(this);
}
另一种启用Mockito注释的方法是通过指定执行此任务的MockitoJUnitRunner和其他有用的事情来使用@RunWith注释测试类:
@RunWith(org.mockito.runners.MockitoJUnitRunner.class)
public MyClassTest{...}
Spring Boot库包装Mockito库
这确实是一个Spring Boot类:
import org.springframework.boot.test.mock.mockito.MockBean;
...
@MockBean
MyService myservice;
该类包含在spring-boot-test库中。
它允许在Spring ApplicationContext中添加Mockito mock。 如果上下文中存在与声明的类兼容的bean,则用mock替换它。 如果不是这样,它将mock作为bean添加到上下文中。
Javadoc参考:
可用于向Spring添加模拟的注释 ApplicationContext。 ... 上下文中定义的任何相同类型的现有单个bean 将被mock取代,如果没有现有的bean被定义为一个新的 将被添加。
什么时候使用经典/普通Mockito,什么时候从Spring Boot使用@MockBean ?
单元测试的设计目的是在组件与其他组件隔离的情况下测试组件,单元测试也有一个要求:在执行时间方面尽可能快,因为这些测试可能每天在开发人员机器上执行十几次。
因此,这里有一个简单的指导方针:
当您编写一个不需要来自Spring Boot容器的任何依赖项的测试时,经典/普通Mockito是遵循的方法:它速度快,有利于测试组件的隔离。 如果您的测试需要依赖Spring Boot容器,并且您还想添加或模拟其中一个容器bean:来自Spring Boot的@MockBean是一种方法。
Spring Boot @MockBean的典型用法
当我们编写带有@WebMvcTest (web测试片)注释的测试类时。
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"));
}
}
Mocktio.mock() :-
将创建类或接口的模拟对象。我们可以用 此模拟用于存根返回值并验证它们是否被调用。 对于模拟对象,必须使用when(..)和thenReturn(..)方法 其类方法将在测试用例执行期间被调用。
@Mock: -
这是mock()方法的简写,因此更可取,而且经常使用 使用。 mock()和@Mock在功能上是等价的。 当字段名称出现在错误消息中时,更容易在模拟失败中识别问题。
为了在测试执行期间启用Mockito注释,我们需要调用MockitoAnnotations.initMocks(this)方法,但是这个方法已弃用,我们可以调用- MockitoAnnotations.openMocks(this)。为了避免副作用,建议在测试用例执行之前调用此方法。
启用Mockito注释的另一种方法是通过指定执行此任务的MockitoJUnitRunner和其他有用的事情,用@RunWith注释测试类。
@MockBean: - 它用于将模拟对象添加到spring应用程序上下文中。 这个模拟将替换应用程序中相同类型的现有bean 上下文。如果没有可用的bean,那么将添加新的bean。这 在集成测试用例中很有用。
当我们编写一个不需要任何来自Spring Boot容器的依赖项的测试用例时,使用经典/普通Mockito,它速度快,有利于被测试组件的隔离。
如果我们的测试用例需要依赖Spring Boot容器,并希望添加或模拟其中一个容器bean,则使用@MockBean。