OAuth 2.0 单元测试解决方案
时间:2022-07-28
本文章向大家介绍OAuth 2.0 单元测试解决方案,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
为什么需要单元测试
单元测试拥有保证代码质量、尽早发现软件 Bug、简化调试过程、促进变化并简化集成、使流程更灵活等优势。单元测试是针对代码单元的独立测试,核心是“独立”,优势来源也是这种独立性,而所面临的不足也正是因为其独立性:既然是“独立”,就难以测试与其他代码和依赖环境的相互关系。单元测试与系统测试是互补而非代替关系。单元测试的优势,正是系统测试的不足,单元测试的不足,又恰是系统测试的优势。不能将单元测试当做解决所有问题的万金油,而需理解其优势与不足,扬长避短,与系统测试相辅相成,实现测试的最大效益。
OAuth2 系统单元测试困难
- 接口测试依赖于 UPMS (用户权限管理),无法做到解耦独立
- spring-security-test 模块未提供相关标准实现
- 场景复杂既要包含无状态 token 调用,又要保证上线文传递业务
解决方案
参考 @WithMockUser ,在 Mock 拦截器中自动执行相关的增强(token 获取),并通过扩展 WithSecurityContextFactory 实现上下文 token 的传递。具体可以参考源码 pig-common-test[1]
引入依赖
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pig-common-test</artifactId>
<version>${last.version}</version>
<scope>test</scope>
</dependency>
单元测试 Controller 接口
- 指定认证中心接口
配置在 test/resources/application.yml
security:
oauth2:
client:
access-token-uri: http://pig-gateway:3000/oauth/token
- 模拟测试 controller 接口
@RunWith(SpringRunner.class)
@SpringBootTest
public class SysLogControllerTest {
private MockMvc mvc;
@Autowired
private WebApplicationContext applicationContext; // 注入WebApplicationContext
@Before
public void setUp() {
this.mvc = MockMvcBuilders.webAppContextSetup(applicationContext).build();
}
@Test
@SneakyThrows
@WithMockOAuth2User
public void testMvcToken() {
mvc.perform(delete("/log/1").with(token())).andExpect(status().isOk());
}
}
模拟测试 FeignClient 传递 token
直接注入 FeignClient 实现即可 使用 @WithMockOAuth2User 注解测试类即可
WithMockOAuth2User 属性说明
- 当前用例获取 token 使用的用户名
String username() default "admin";
- 当前用例获取 token 使用的密码
String password() default "123456";
写在最后 源码参考 pig-common-test 模块 目前仅在 pig 2.10 做了实现,理论支持低版本,直接 install 此模块即可
- 零基础学编程009:只显示2位小数
- .Net实现Windows服务安装完成后自动启动的两种方法
- 【教程】OpenCV—Node.js教程系列:Node.js+OpenCV面部脸识别
- 学会10多种语言是种什么样的体验?
- Spring Data 最佳实践
- Prodigy,从根本上有效的自主学习驱动的注释工具
- 零基础学编程017:画出我的公众号LOGO
- 一个实用的却被忽略的命名空间:Microsoft.VisualBasic
- Spring @RequestBody 传递 List/Map 参数
- win7怎么去除快捷方式的小箭头
- 零基础学编程015:画些有趣的图案
- Spring boot with Thymeleaf
- 零基础学编程014:小海龟做画
- Springboot @RequestBody 传递 List
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Linux系统Shell编程——脚本编写思路与过程
- python第三十六课——2.迭代器对象
- python第三十七课——模块
- Linux系统MySQL数据库主从同步实战过程
- 最火的java8新特性:Lambda 表达式
- python第三十九课——面向对象(二)之设计类
- python第三十九课——面向对象(二)之初始化属性
- LVS服务DR模式安装布署过程
- python第四十课——构造函数
- python第四十一课——析构函数
- python第四十二课——__str__(self)函数
- python第四十三课——封装性
- Nginx+Tomcat多实例及负载均衡配置
- python第四十四课——继承性之单继承
- python第四十五课——继承性之多重继承