专栏首页软件测试那些事单测实例-void方法验证

单测实例-void方法验证

单元测试-更新项目

利用MeterSphere更新项目的方法来介绍

1)如何对void方法进行测试

2)如何捕获写库入参并验证

3)继续使用Mockito-inline来mock静态方法

以下是被测对象updateProject(Project project),以及经过测试之后的代码覆盖情况。

这个方法首先检查了待更新的测试项目是否在当前workspace下存在重名,如果没有重名的话,则通过projectMapper对该测试项目进行写库更新其信息。

我们编写两个用例

1)存在重名,方法抛出异常

2)检查通过,项目更新成功

存在重名,方法抛出异常

首先来看一下第一个用例

  • @Test public void updateProjectServiceNameShouldNotDuplicate(){ String expected ="project_name_already_exists"; Project project= new Project(); project.setName("name"); project.setId("id"); List<Project> projects= new ArrayList<>(); projects.add(project); Mockito.when(projectMapper.selectByExample(Mockito.any(ProjectExample.class))).thenReturn(projects); //数据库中已存在记录条数为1 try ( MockedStatic<Translator> translator= Mockito.mockStatic(Translator.class); MockedStatic<SessionUtils> sessionUtils= Mockito.mockStatic(SessionUtils.class); ){ sessionUtils.when(() -> { SessionUtils.getCurrentWorkspaceId();}).thenReturn("id"); translator.when(() -> Translator.get("project_name_already_exists")).thenReturn(expected); assertThatThrownBy(() -> projectService.updateProject(project)).hasMessage(expected); } }

这里使用的是之前关于测试计划的单元测试中已经使用过的测试工具Mockito-inline来mockSessionUtils.getCurrentWorkspaceId()和Translator.get("project_name_already_exists")这两个静态方法,形成有效的测试桩让测试用例能顺利覆盖测试点。

检查通过,项目更新成功

接下来,来看下如何完成测试项目更新的测试用例

 package io.metersphere.service;
 
 import io.metersphere.base.domain.Project;
 import io.metersphere.base.domain.ProjectExample;
 import io.metersphere.base.mapper.ProjectMapper;
 import io.metersphere.commons.utils.SessionUtils;
 import io.metersphere.i18n.Translator;
 import net.javacrumbs.jsonunit.core.Option;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.*;
 import org.mockito.junit.jupiter.MockitoExtension;
 import org.springframework.test.context.junit.jupiter.SpringExtension;
 
 import java.util.ArrayList;
 import java.util.List;
 
 import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.mockito.Mockito.verify;
 
 @ExtendWith(SpringExtension.class)
 @ExtendWith(MockitoExtension.class)
 public class ProjectServiceUpdateProjectTest {
     @Mock
     private ProjectMapper projectMapper;
 
     @InjectMocks
     ProjectService projectService;
 
     @Captor
     ArgumentCaptor<Project> projectArgumentCaptor;
 
     @Test
     public void updateProjectSuccess(){
         Project project= new Project();
         project.setName("name");
         project.setId("id");
         List<Project> projects= new ArrayList<>();
         Mockito.when(projectMapper.selectByExample(Mockito.any(ProjectExample.class))).thenReturn(projects);
         //利用Mockito-inline来mock静态方法
         // 数据库中已存在记录条数为0
         try ( MockedStatic<SessionUtils> sessionUtils=  Mockito.mockStatic(SessionUtils.class);
         ){
             sessionUtils.when(() -> { SessionUtils.getCurrentWorkspaceId();}).thenReturn("id");
             //调用被测方法,请注意返回值是void类型
              projectService.updateProject(project);
              //验证写库并获取写库的入参进行进一步验证
           verify(projectMapper).updateByPrimaryKeySelective(projectArgumentCaptor.capture());
            Project projectCapture = projectArgumentCaptor.getValue();
            //断言更新时间非空,并且更新内容是入参
            assertThat(projectCapture.getUpdateTime()).isNotNull();
             assertThatJson(project).when(Option.IGNORING_EXTRA_FIELDS).isEqualTo(projectCapture);
         }
     }
 
 
 }

由于updateProject是一个返回值为void的方法,如何来验证测试项目更新成功呢?笔者采用了以下的验证点

1)Project写库,即projectMapper.updateByPrimaryKeySelective(project)方法被调用一次

2)写库内容符合预期,如id/name是入参提供的,更新时间非空

这里,我们使用了Mockito的verify来验证mapper方法是否被调用。用ArgumentCaptor来获取mapper方法的入参,并进行验证。

当然,从代码健壮性的角度来看,也建议MeterSphere对Project入参提供一下统一的检测方法,如project非空、name非空等等。

本文分享自微信公众号 - 软件测试那些事(antony-not-available),作者:风月同天测试人

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-12-12

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 2021第一篇-流量录制回放完整案例

    在之前的《录制回放实现测试用例自由》一文中,笔者简单介绍了如何通过切面来录制HTTP接口请求和返回,并实现了用例的回放。 当然,在实际的项目中,对于应用来说,除...

    Antony
  • 如何用Junit5玩出参数化测试的新花样?

    这是之前一篇文章《用junit5编写一个类ZeroCode的测试框架》的续集。主要将在之前工作的基础上,围绕参数化测试展开。 框架主要设计点:

    Antony
  • 使用MockMVC进行Controller单元测试

    由于MockMVC是Spring框架自带的测试组件,因此只要在项目中引入spring-boot-starter-test这个测试套件就可以使用Spring-te...

    Antony
  • 使用shiro安全管理

    dalaoyang
  • 使用beanUtils操纵javabean

    package com.lan.beanutils; import java.lang.reflect.InvocationTargetExcepti...

    MonroeCode
  • 太狠了,疫情期间面试,一个问题砍了我5000!

    我:@Value可以标注在字段上面,可以将外部配置文件中的数据,比如可以将数据库的一些配置信息放在配置文件中,然后通过@Value的方式将其注入到bean的一些...

    路人甲Java
  • 使用Java代码在SAP Marketing Cloud上创建Contact数据

    Jerry Wang
  • 如何用Java代码在SAP Marketing Cloud里创建contact数据

    我们可以使用SAP Marketing Cloud提供的Contact create OData API在第三方应用里创建Contact主数据.

    Jerry Wang
  • day18_文件的上传和下载学习笔记

    作用:告知服务器请求正文的MIME类型(文件类型)。(与请求消息头中:Content-Type作用是一致的) 可选值:

    黑泽君
  • springboot+security 数据库中读取账号密码 使用security加密规则 实体类继承security的实体接口

    码云地址:https://gitee.com/huatao1994/springSecurity

    用户5899361

扫码关注云+社区

领取腾讯云代金券