为什么需要单元测试

单元测试拥有保证代码质量、尽早发现软件 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 此模块即可

项目推荐: Spring Cloud 、Spring Security OAuth2的RBAC权限管理系统 欢迎关注

OAuth 2.0 单元测试解决方案的更多相关文章

  1. ASP.NET WebApi OWIN 实现 OAuth 2.0

    OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用. OAuth 允许用户提供一个令牌, ...

  2. 谈谈基于OAuth 2.0的第三方认证 [上篇]

    对于目前大部分Web应用来说,用户认证基本上都由应用自身来完成.具体来说,Web应用利用自身存储的用户凭证(基本上是用户名/密码)与用户提供的凭证进行比较进而确认其真实身份.但是这种由Web应用全权负 ...

  3. NET WebApi OWIN 实现 OAuth 2.0

    NET WebApi OWIN 实现 OAuth 2.0 OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和 ...

  4. c#实现Google账号登入授权(OAuth 2.0)并获取个人信息

    c#实现Google账号登入授权(OAuth 2.0)并获取个人信息   此博主要介绍通过google 账号(gmail)实现登入,授权方式OAuth2.0,下面我们开始介绍. 1.去google官网 ...

  5. IdentityServer4 实现 OpenID Connect 和 OAuth 2.0

    关于 OAuth 2.0 的相关内容,点击查看:ASP.NET WebApi OWIN 实现 OAuth 2.0 OpenID 是一个去中心化的网上身份认证系统.对于支持 OpenID 的网站,用户不 ...

  6. Dynamics CRM 配置 OAuth 2.0

    关注本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复124或者20140324可方便获取本文,同时可以在第一时间得到我发布的最新的博文信息,follow me! 本博文主要参考但不限于如下资料: ...

  7. OAuth 2.0协议在SAP产品中的应用

    阮一峰老师曾经在他的博文理解OAuth 2.0里对这个概念有了深入浅出的阐述. http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html 本文会结合我 ...

  8. OAuth 2.0 授权认证详解

    一.认识 OAuth 2.0 1.1 OAuth 2.0 应用场景 OAuth 2.0 标准目前被广泛应用在第三方登录场景中,以下是虚拟出来的角色,阐述 OAuth2 能帮我们干什么,引用阮一峰这篇理 ...

  9. [转]ASP.NET WebApi OWIN 实现 OAuth 2.0

    OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用. OAuth 允许用户提供一个令牌, ...

随机推荐

  1. 无所不能的Embedding7 - 探索通用文本表达[FastSent/InferSent/GenSen/USE]

    在4/5章我们讨论过用skip-thought,quick-thought任务来进行通用文本向量提取,当时就有一个疑问为什么用Bookcorpus这种连续文本,通过预测前一个和后一个句子的方式得到的文 ...

  2. list.add(int index, E element)和list.addAll(list1)

    List.add(int index, E element): 在列表的指定位置插入指定元素(可选操作).将当前处于该位置的元素(如果有的话)和所有后续元素向右移动(在其索引中加 1). 参数:ind ...

  3. eclipse自定义快捷键

    eclipse系统自带的快捷键设置有时候使用起来并不习惯,可以自定义某些常用的快捷键. 依次打开 Window->Preference->General->Keys,这里显示了所有的 ...

  4. clipse中mybatis的xml配置文件代码提示

    编写mybatis的xml文件时,没有代码提示会很麻烦,是有解决办法的: 按下图打开 点击右上角的Add按钮,添加配置,配置如下,添加后点击OK: Location:http://mybatis.or ...

  5. Java基本概念:多态

    一.简介 描述: 多态性是面向对象编程中的一个重要特性,主要是用来实现动态联编的.换句话说,就是程序的最终状态只有在执行过程中才被决定,而非在编译期间就决定了.这对于大型系统来说能提高系统的灵活性和扩 ...

  6. COM技术中的VARIANT and VARIANTARG

    VARIANT and VARIANTARG Use VARIANTARG to describe arguments passed within DISPPARAMS, and VARIANT to ...

  7. docker mysql初始化多个sql脚本

    一.概述 现有一台服务器,需要部署mysql.其中mysql容器,需要在第一次启动时,执行多个sql文件. 文件名 说明 执行顺序 init.sql 创建数据库以及用户 1 users.sql 用户表 ...

  8. python进阶(12)闭包

    闭包 首先了解一下:如果在一个函数的内部定义了另一个函数,外部的我们叫他外函数,内部的我们叫他内函数. 在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用 ...

  9. 一个页面中多个window.onload = function(){}冲突问题解决思路

    转: 一个页面中多个window.onload = function(){}冲突问题解决思路 一个页面中多个window.onload = function(){}冲突问题解决思路 参考文章: (1) ...

  10. mysql基本指令2

    pymysql:  - 连接.关闭(游标)  - execute()   -- SQL注入    sss' or 1=1 --   - 增删改: conn.commit()  - fetchone f ...