IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> 单元测试进阶-Mockito工具 -> 正文阅读

[开发测试]单元测试进阶-Mockito工具

单元测试进阶Mockito工具

一、概述

1.Mockito是什么工具

Mockito框架可以创建和配置mock对象,简化具有外部对象依赖的类的测试开发。

2.项目中引入Mockito

Maven引入依赖

<!-- https://mvnrepository.com/artifact/org.mockito/mockito-core -->
<dependency>
  <groupId>org.mockito</groupId>
  <artifactId>mockito-core</artifactId>
  </dependency>

// 初始化Mockito,或者junit4中使用@Runwith(MockitoJunitRunner.class)
MockitoAnnotations.openMocks(this);

二、思想及使用方法

1.@TestInstance注解

在使用Mockito之前需要初始化,在junit4中可以使用@Runwith(MockitoJunitRunner.class)设置运行器。但是junit5中暂未找到设置运行器的注解,因此我在@BeforeAll注解中将其初始化。

随之而来的问题是,初始化需要使用到this,并且@BeforeAll注解的方法需要是static方法。这两个是冲突的,因此需要在类上加上@TestInstance注解,如下

@TestInstance(TestInstance.Lifecycle.PER_CLASS)

2.@InjectMocks注解

该注解用于被测试的类上,被它注解的类,方法会真实的执行。

当该测试类遇到使用@Mock注解的依赖时,会使用被虚拟后的对象

3.@Mock注解

使用@Mock注解的类会创建一个完全虚拟的实例,方法和属性都是空值,不会真实执行。

用于创建被测试类的依赖使用,如对Dao或Service的Mock

三、示例

1.对Service的测试,对Dao的Mock

当我们做好Mockito的初始化,及定义好需要@InjectMocks的类和需要@Mock的类后,我们就可以在测试方法中对mock做文章了。

测试方法中最重要的操作是在执行service的方法之前的语句:

Mockito.when(userDao.findByNameAndPasswd(Mockito.anyString(), Mockito.anyString()))
.thenReturn(mockUser);

这个方法定义了,当dao的某个方法被执行时,将会使用mock的数据返回,由此后面的操作将得到mock数据结果。

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@Slf4j
public class MockitoTest {
    // 需要测试的类,会创建真实实例
    @InjectMocks
    private UserServiceImpl userService;
    // 方法中依赖的类,会创建虚拟的mock
    @Mock
    private UserDao userDao;

    @BeforeAll
    public void setUp() throws Exception {
        log.info("测试开始");
        // 初始化Mockito,或者junit4中使用@Runwith(MockitoJunitRunner.class)
        MockitoAnnotations.openMocks(this);
    }
    @AfterAll
    public void tearDown() {
        log.info("测试结束");
    }

    @Test
    public void testServiceSignIn() {
        // 创建返回的模拟用户数据:王五
        UserDO mockUser = UserDO.builder().name("王五").password("王五的密码").build();
        // 对方法调用dao时进行mock处理
        Mockito.when(userDao.findByNameAndPasswd(Mockito.anyString(), Mockito.anyString()))
                .thenReturn(mockUser);

        // 测试的方法执行登录操作获得mock数据返回
        String result = userService.signIn("王五", "王五的密码");
        log.info("mock返回结果:{}", result);
        Assertions.assertEquals("王五,欢迎回来", result);
    }
}

测试结果

INFO com.flamingo.junit5test.MockitoTest - 测试开始
INFO com.flamingo.junit5test.MockitoTest - mock返回结果:王五,欢迎回来
INFO com.flamingo.junit5test.MockitoTest - 测试结束

2.对Controller的测试,对Service的Mock

对controller的测试中,使用mockmvc发送的HTTP请求测试,因为Mockito没有接管到其中的service执行,所以还是走的真实的service方法。

而使用controller类直接调用方法时,service使用的就是Mockito生成的mock对象,因此可以返回期望的mock数据

		@Autowired
    private MockMvc mockMvc;
    @InjectMocks
    private UserController userController;
    @Mock
    private UserService userService;

    private static final ObjectMapper MAPPER = new ObjectMapper();

    @BeforeAll
    public void setUp() throws Exception {
        log.info("测试开始");
        // 初始化Mockito,或者junit4中使用@Runwith(MockitoJunitRunner.class)
        MockitoAnnotations.openMocks(this);
    }    

		@Test
    public void testControllerSignIn() throws Exception{
        // 创建返回的模拟用户数据:赵六
        UserDO mockUser = UserDO.builder().name("赵六").password("赵六的密码").build();
        // 对方法调用service时进行mock处理
        Mockito.when(userService.signIn(Mockito.anyString(), Mockito.anyString()))
                .thenReturn("赵六,欢迎回来");

        // 测试的方法执行登录操作获得mock数据返回
        RequestBuilder requestBuilder = MockMvcRequestBuilders.post("/user/signIn")
                .contentType(MediaType.APPLICATION_JSON)
                .content(MAPPER.writeValueAsString(mockUser));

        MvcResult mvcResult = mockMvc.perform(requestBuilder)
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andDo(MockMvcResultHandlers.print())
                .andReturn();

        log.info("【用户登录】{}", mvcResult.getResponse().getContentAsString());

        String result = userController.signIn(mockUser);
        log.info("【Mock用户登录】{}", result);
    }

测试结果

UserControllerTest      : 【用户登录】用户名或密码不正确
UserControllerTest      :Mock用户登录】赵六,欢迎回来

四、总结及更多

? Mockito除了上面示例中的mock Dao 和 Service之外,还可以mock对象、数据等。简而言之是万物皆可Mock。另外Mockito还有涉及很多其它一些方法及特性,如验证行为、参数匹配、重复执行等,可另行查阅资料进行学习了解。

  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2021-08-29 09:39:58  更:2021-08-29 09:40:29 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/11 5:09:37-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码