卓越工程之单元测试在行权鉴权中的实践(代码片段)

阿里云云栖号 阿里云云栖号     2022-12-16     430

关键词:

前言

在去年的时候就读过《重构:改善既有代码的设计》这本在代码重构领域里的经典,当时在读的时候就苦于有这么两点导致只停留在了“读”上面,而缺少实践。

1.全书内容比较枯燥乏味,虽然有部分代码示例,但是语言并不生动,让人坚持读下去就很难。

2.书中强调,每做一次代码的重构,即使修改很小的部分,也应该对修改进行测试,所以在看到书中举例的各种重构和重构后的不断测试时,就对测试和重构打起了退堂鼓

因为对代码的测试缺少整体的认知,对单元测试也一直停留在简单的print层面,直到在这几天通过一个阅读打卡活动,系统性的学习了大量关于单元测试的理论、实践知识和在代码重构中的帮助,重新让我回忆起《重构》书中所提到的知识点,一直跃跃欲试,所以也想尝试将单元测试实际应用在自己写的业务代码中,为自己的代码“保驾护航”,同时在代码中有单测,在重构的过程中单测也会让自己不慌张,修改代码后直接执行一下单测就可以对修改后的准确性进行验证。这篇文章着重在“实践”上,是对Java编程技巧之单元测试用例编写流程这篇文章的实际应用,并没有高深的理论和技术。

流程

包括单元测试在内的所有测试都应该对所需要测试的流程有比较清晰的认识才能保证测试的用例不被遗漏,保证测试质量,因此在撰写单元测试前,首先需要对所测试部分代码的流程进行梳理。

1.用户发起查询时,首先判断用户传入的参数中是否包含行权验证的字段,如果不包含则直接抛出异常,提示鉴权失败;

2.在鉴权中,因为行权可能会由多个字段组合鉴权,因此需要对全部鉴权字段进行遍历。在鉴权时,还会有匹配字段,包含:

  • 等值匹配(=)
  • 前缀匹配(like xxx%)
  • 后缀匹配(like %xxx)
  • 模糊匹配(like %xxx%)

四种形式,当用户输入参数与匹配字段不相符时,记作鉴权失败。

3.当用户没有输入参数中的权限时,记作鉴权失败。

4.在多个鉴权字段进行组合时,还会存在两种组合逻辑:and(所有字段均需要有权限才能访问)和 or(任意字段有权限即可访问),所以还会结合组合逻辑进行综合权限判定。

测试边界

在明确了代码的流程后,就需要对测试边界进行明确,测试应该着重对边界情况进行测试,因为清晰的单元测试边界划分有利于构建更加稳定的系统核心代码,因为我们在推进测试边界的过程中会不断地将副作用从核心代码中剥离出去,最终会得到一个完整且可测试的核心,而我们的核心代码就是处于测试边界内的。下图将所有的情况做了枚举,作为单元测试的用例。

撰写单元测试

引入依赖

<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-core</artifactId>
    <version>$powermock.version</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-api-mockito2</artifactId>
    <version>$powermock.version</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-module-junit4</artifactId>
    <version>$powermock.version</version>
    <scope>test</scope>
</dependency>

其中,powermock.version为2.0.9,为当前的最新版本,可根据实际情况修改。在PowerMock包中,已经包含了对应的Mockito和JUnit包,所以无需单独引入Mockito和JUnit包。

模拟方法

1.首先是需要对外部依赖和进行测试的类进行模拟和注入:

   // 需要模拟的外部依赖
    @Mock
    private ArkDataSetReadService arkDataSetReadService;
    
    // 需要进行测试的类
    @InjectMocks
    private ComponentJobExecuteService componentJobExecuteService;

2.之后就是对依赖的方法进行模拟:

Response<RowPermissionQueryResponseDto> response = JSON.parseObject(permissionData, Response.class);

Mockito.doReturn(response).when(arkDataSetReadService).getUserRowPermissions(911L, 1741141);

●通过文本的方式构造模拟的返回值。

●通过Mockito.doReturn() 方法模拟调用时的返回值。

3.最后就是对所测试的方法进行测试:

Map<String, Pair<String, List<String>>> filterParams = new HashMap<>();


Whitebox.invokeMethod(componentJobExecuteService, "checkRowPermission", 911L, filterParams)

完整的测试代码:

@Test(expected = AuthException.class)
    public void testRowPermission() throws Exception 
       
        ContextInfo contextInfo = new ContextInfo();
        contextInfo.setBucId(1741141);
        ContextInfoHolder.setContextInfo(contextInfo);
       
        Response<RowPermissionQueryResponseDto> response = JSON.parseObject(permissionData, Response.class);

        Mockito.doReturn(response).when(arkDataSetReadService).getUserRowPermissions(911L, 1741141);

        Map<String, Pair<String, List<String>>> filterParams = new HashMap<>();

        Whitebox.invokeMethod(componentJobExecuteService, "checkRowPermission", 911L, filterParams);
    

因为在没有权限的时候会直接抛出 AuthException,所以通过@Test(expected = AuthException.class) 进行验证。

到此,行权验证的单元测试框架就初步搭建完成,接下来就是根据前面梳理的单元测试用例的边界构建不同的参数进行验证。

总结

在实际撰写单元测试时,由于对工具的不熟悉担心写起来比较麻烦,所以一直没进行尝试,但是在实际操作的时候发现,在写单元测试的时候,其实也是对整个代码进行梳理的过程,是对自己写代码时思路的复盘和总结,单测不只是能验证代码执行的准确性,还能验证在写代码时的逻辑是否正确、能否满足业务的实际需求。

有了单测打底,接下来即使需要对这部分代码进行重构、迭代,也能做到心中有数,只需要在重构完成后执行下单测就可以轻松验证代码的准确性。

希望能够通过这次实践,能够让自己在写单测的路上坚持下去。

作者 | 邱庆羽(羽哲)

原文链接

本文为阿里云原创内容,未经允许不得转载。

软件工程实践总结

这个作业属于哪个课程2021春软件工程实践这个作业要求在哪里软件工程实践总结&个人技术博客这个作业的目标课程回顾与总结、个人技术总结其他参考文献软工实践寒假作业(2/2)、《构建之法》课程回顾与总结问题分析点... 查看详情

一文带你进行go语言工程实践(代码片段)

文章目录并发和Goroutine并发和并行的区别线程与协程的区别Goroutine用法并发的通信Channel并发安全依赖管理GOPATHGOPATH弊端GoVendorGoVendor弊端GoModule(最终解决方案依赖管理三要素配置文件版本规则杂项中心仓库管理依赖库依赖的... 查看详情

软件工程实验五---单元测试(代码片段)

软件工程实验五——单元测试一、实验目的掌握单元测试的方法学习XUnit测试原理及框架掌握使用测试框架进行单元测试的方法和过程二、实验内容与要求了解单元测单元测试(unittesting),是指对软件中的最小可测试单元进行... 查看详情

.net单元测试的艺术&单元测试之道c#版(代码片段)

目录1.单元测试概念2.单元测试的原则3.单元测试简单示例4.单元测试框架特性标签5.单元测试中的断言Assert6.单元测试中验证预期的异常7.单元测试中针对状态的间接测试8.单元测试在MVC模式中的实现8.单元测试相关参考9.示例源代... 查看详情

研效优化实践:python单测——从入门到起飞(代码片段)

作者:uniquewang,腾讯安全平台后台开发工程师福生于微,积微成著,一行代码的精心调试,一条指令的细心验证,一个字节的研磨优化,都是影响企业研发效能工程的细节因素。而单元测试,是指... 查看详情

软件工程之词频统计(代码片段)

代码:https://github.com/jackroos/word_frequencyhowyoucollaborate:workingseparately? pairprogramming?VSLiveShare?otherstyle?首先我们一起讨论了代码结构,如何用python实现来更快的进行词频统计。然后是分工合作,队友负责python实现,我负责代码复审... 查看详情

第三次软件工程作业——覆盖标准,自动单元测试复习,github之使用。(代码片段)

0.背景问题:给定n个整数(可能为负数)组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。当所给的整数均为负数时定义子段和为0,依此定义,所求的最优值为:Max0,a[i]+a[i+1]+…+a[j],1<=i<=j<=n例如... 查看详情

20171130-构建之法:现代软件工程-阅读笔记

我阅读了第二章:个人技术和流程 1)个人编写模块时要有单元测试,毕竟最后的软件是由多人合作完成的。我们要确保我们所写的模块能被他人调用,并且代码清晰易懂,不影响其他模块。用vsts写单元测试我们没有接触过,... 查看详情

工程实践之路:c++接口设计中的工厂模型(代码片段)

工程实践之路:C++接口设计中的工厂模型设计模式之工厂模式为什么使用工厂模式1.工厂设计模式是为了将对象的创建与使用进行分离2.其他好处简单工厂模式工厂方法模式抽象工厂模式参考资料上一篇文章写了《工程... 查看详情

20170927-构建之法:现代软件工程-阅读笔记

单元测试的几个特性:单元测试应该在最基本的功能/参数上验证程序的正确性。单元测试必须由最熟悉代码的人来写。单元测试过后,机器状态保持不变。单元测试要快单元测试应该产生可重复、一致的结果。独立性---单元测... 查看详情

测试环境治理之mysql索引优化篇(代码片段)

...的呢?所谓“理想很丰满,现实很骨感”,对于一线测试工程师可能会发现,真实的测试环境并非这么理想。测试同学算是测试环境的主要使用者,对测试环境的管理理应负有直接责任。不过 查看详情

吃透单元测试:spock单元测试框架的应用与实践(代码片段)

一,单元测试单元测试是对软件基本组成单元进行的测试,如函数或一个类的方法。程序是由函数组成的,每个函数都要健壮,这样才能保证程序的整体质量。单元测试是对软件未来的一项必不可少的投资。”具... 查看详情

androidcompose单元测试实践(代码片段)

前言做Android开发多年,一直欠下不少单元测试的账,最近发现Compose这套新的UI系统可以单元测试,初步做了一下调研,发现可行,因为有官方的背书。学到什么Compose集成官方支持的页面单元测试方法HiltDagger2... 查看详情

2022-9月报

...端与服务端双实现如何写出有效的单元测试从软件工程到卓越工程,单元测试从可选变成了必要;想要实现主干开发、大库模式,单元测试是前提条件。关于单元测试这件事,我觉得最重要永远是写单元测试的人&... 查看详情

吃透单元测试一,spock单元测试框架的应用与实践(代码片段)

一,单元测试单元测试是对软件基本组成单元进行的测试,如函数或一个类的方法。程序是由函数组成的,每个函数都要健壮,这样才能保证程序的整体质量。单元测试是对软件未来的一项必不可少的投资。”具... 查看详情

swift之深入解析如何避免单元测试中的强制解析(代码片段)

一、前言强制解析(使用!)是Swift语言中不可或缺的一个重要特点(特别是和Objective-C的接口混合使用时),它回避了一些其他问题,使得Swift语言变得更加优秀。比如在我的博客Swift之深入解析如何处理非... 查看详情

20171005-构建之法:现代软件工程-阅读笔记

今天我阅读了关于单元测试的内容:发现这一部分在今后的工作中非常重要可以有效减少程序的bug以及出现的问题单元测试的几个特性:单元测试应该在最基本的功能单元测试必须由最熟悉代码的人来写。单元测试过后,机器状... 查看详情

构建之法现代软件工程(第二次)

...                 构建之法现代软件工程(第二次)单元测试是什么?  单元测试是为了让各个模块的质量能得到稳定的,量化的保证的一种有效解决方案。(VSTS) 好的单元测试的标准是什么?  1.... 查看详情