junit @Mock、@MockBean和Mockito之间的区别.mock()

2lpgd968  于 2022-11-11  发布在  其他
关注(0)|答案(3)|浏览(186)

在创建测试和模拟依赖项时,这三种方法有什么区别?
1.@模仿豆:

@MockBean
MyService myservice;

1.@模拟:

@Mock
MyService myservice;
  1. Mockito.模拟()
MyService myservice = Mockito.mock(MyService.class);
06odsfpq

06odsfpq1#

纯Mockito程式库

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{...}

Package Mockito库的Sping Boot 库

这确实是一个Spring Boot class

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

类别包含在spring-boot-test程式库中。
它允许在Spring ApplicationContext中添加Mockito模拟。
如果上下文中存在一个与声明的类兼容的bean,它会用mock替换它。
如果不是这种情况,它会将mock作为bean添加到上下文中。
Javadoc参考:
可用于将模拟添加到Spring ApplicationContext的注解。
...
如果在上下文中定义的相同类型的任何现有单个Bean将被mock替换,则如果未定义现有Bean,则将添加一个新Bean。

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

单元测试旨在测试与其他组件隔离的组件,并且单元测试也有一个要求:在执行时间方面尽可能快,因为这些测试可以在开发者机器上每天执行几十次。
因此,这里有一个简单的指导原则:
当您编写一个不需要任何来自Sping Boot 容器的依赖项的测试时,经典/普通Mockito是遵循的方法:它是快速的并且有利于被测部件的隔离。
如果您的测试需要依赖于Sping Boot 容器,您还需要添加或模拟其中一个容器Bean:来自Sping Boot 的@MockBean是方法。

Spring Boot @MockBean的典型用法

当我们编写一个用@WebMvcTest(web测试切片)注解的测试类时。
Sping 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"));
    }

}
djmepvbi

djmepvbi2#

最后很容易解释。如果你只看一下注解的javadoc,你就会看到不同之处:
@模拟:(org.mockito.Mock
将字段标记为模拟。

  • 允许速记模拟创建。
  • 最大限度地减少重复的模拟创建代码。
  • 使测试类更可读。
  • 使验证错误更易于阅读,因为字段名称用于标识模拟。

@模拟Bean:(org.springframework.boot.test.mock.mockito.MockBean
可用于将模拟添加到Spring ApplicationContext的注解。可用作类级别注解,或用于@Configuration类或@RunWith SpringRunner测试类中的字段。
可以按类型或Bean名称注册模拟。在上下文中定义的相同类型的任何现有单个Bean都将被模拟替换,如果未定义现有Bean,则将添加一个新Bean。
@MockBean被用在一个字段上,并且被注册到应用程序上下文中时,mock也将被注入到该字段中。
Mockito.模拟()
它只是一个@Mock的表示。

3yhwsihp

3yhwsihp3#

模拟():-
1.将创建一个类或接口的模拟对象。我们可以使用这个模拟来存根返回值并验证它们是否被调用。
1.我们必须为mock对象使用when(..)thenReturn(..)方法,这些对象的类方法将在测试用例执行期间被调用。
@Mock:-
1.这是mock()方法的简写,因此它是首选的,并且经常使用。

  1. mock()@Mock在功能上是等效的。
    1.由于错误消息中显示了字段名称,因此更易于识别模拟故障中的问题。
    要在测试执行期间启用Mockito注解,我们需要调用MockitoAnnotations.initMocks(this)方法,但此方法已被弃用,我们可以调用-MockitoAnnotations.openMocks(this)。为了避免副作用,建议在测试用例执行之前调用此方法。
    启用Mockito注解的另一种方法是通过指定执行此任务和其他有用操作的MockitoJUnitRunner,使用@RunWith注解测试类。
    @MockBean:-用于将模拟对象添加到Spring应用程序上下文中。此模拟将替换应用程序上下文中现有的相同类型的bean。如果没有可用的bean,则将添加新的bean。这在集成测试用例中很有用。
    当我们编写一个不需要来自Sping Boot 容器的任何依赖项的测试用例时,将使用经典/普通Mockito,它速度很快,有利于隔离被测试的组件。
    如果我们的测试用例需要依赖于Sping Boot 容器,并且想要添加或模拟其中一个容器bean,那么就使用@MockBean

相关问题