您当前的位置:首页 > 电脑百科 > 程序开发 > 框架

Spring的Mock测试你用上了吗?

时间:2020-08-06 11:26:56  来源:  作者:

在真实的测试当中,并不能所有的逻辑都可以自己控制,因此有了mock测试。今天就结合场景来讲一下怎么做mock测试。

适合对象:初次尝试集成和使用mockito进行单元测试的开发同学

Spring的Mock测试你用上了吗?

 

Mock框架的集成

这里选择的是Mockito + PowerMockito。为什么会集成PowerMockito,是因为有个想要mock的方法是static方法。这个需要PowerMockito,假如都只是普通类,就可以不用了。

集成关键点如下

1、版本对应:这两个mockito的版本是有一个对应关系,假如不对应,会出现类找不到的情况。比如 ClassNotFound org/mockito/mockitoframework 。而网上也已经有对应关系如下链接

https://github.com/powermock/powermock/wiki/Mockito#supported-versions

这是我的集成版本

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

2、注解方式集成:因为使用spring boot的项目,所以考虑怎么用注解方式集成。最后我的注解方案如下所示

@RunWith(PowerMockRunner.class)
@PrepareForTest({JdbcClient.class})
@PowerMockRunnerDelegate(SpringJUnit4ClassRunner.class)
@PowerMockIgnore({"JAVAx.net.ssl.*","javax.management.*", "javax.security.*", "javax.crypto.*"})

这几个,都有自己的用处,分别说下:

  • @RunWith(PowerMockRunner.class) :假如要使用powermock,那就需要配置这个,不然powermock无法使用
  • @PrepareForTest({JdbcClient.class}) :这里的列表,设定的是需要static mock 的类,我的测试场景中,需要mock JdbcClient的static query 方法
  • @PowerMockRunnerDelegate(SpringJUnit4ClassRunner.class) : 一开始,只配置了前两个,然后发现从spring中inject注入的service都为空了。原来要需要使用这个注解,这样就和spring test 组合上了
  • @PowerMockIgnore({"javax.net.ssl.*","javax.management.*","javax.security.*","javax.crypto.*"}) :PowerMock大概是mock的太多了,所以假如没有这行注释,也是各种报错。 ClassCastException: class sun.security.provider.ConfigFile 这种。

TIPS:这些注解可以写到一个abstract TestClass 上,后面的测试类继承这个就方便了

Mock场景举例

好,正式开始mock。首先来讲,网上那些例子,好多都太简单了,不能当做实际场景。比如mock ClassA.method1,然后直接验证method1的结果。这种只能验证集成的对不对。还是结合真实场景比较好。

场景一:修改外部服务调用,比如调用支付宝支付,或者发个短信什么的,也可以是数据库查询

有时候,我们不希望真的去调用外部(比如配置太复杂,比如收费,比如想模拟错误结果)。或者想自己控制数据库查询结果(或者遇到了我这边只有正式环境才有某个库的情况)。那这时候,就需要使用Mock Service来解决。

先撸代码,再分析。

这个场景讲解mock的常规使用手法
以及在spring注入service情况下,如何处理mock

public class MockitoTest extends BaseTest {

    @Autowired
    DemoService demoService;

    @Mock
    RemoteService remoteService;

    @Test
    public void testHack() throws Exception {

        demoService.setRemoteService(remoteService);

        String result = "fail";
        Mockito.when(remoteService.sendRequest(any())).thenReturn(result);

        String callResult = demoService.callRemote("something");
        assertEquals("fail", callResult);

        Mockito.verify(remoteService).sendRequest(any());
    }
}

这个场景感觉用的挺多的。demoService是想要测试的功能,其中用到了remoteService.sendRequest的结果。而又不想实际调用remoteService。这时候就可以先把remoteService.sendRequest给mock掉,给出自己设定的返回结果。

这时候要注意的一个点是:remoteService并不归属springContext管理,所以run test 以后,会发现,这个mock毫无作用。debug之下,可以看到注入和mock的remoteService并不是一个实例。

那如何使remoteSerivce变成mockService,这里有两个思路。

一、就是上面的方案,用mockSerivce去替换demoSerivce里的remoteService。

demoService.setRemoteService(remoteService);

二、替换springContext里面的remoteSerice,这就需要使用@MockBean 这个注解。 然后,所有注入的remoteService,都是Mock生成的service

    @MockBean
    RemoteService remoteService;

但是据说MockBean有副作用,会多次重启Spring context。可能也会污染上下文。暂时没有去尝试研究。

场景二:修改静态类方法,比如一些单例的方法。

在我的场景里,是自定义了一个单例JdbcClient,client保存连接池,然后发起请求。

这个是使用PowerMockito,因为只有他能mock static方法

先来代码

public class MockitoTest extends BaseTest { 

    @Autowired
    DemoService demoService;


    @Test
    public void testHack() throws Exception {


        String result = "fail";
        PowerMockito.mockStatic(JdbcClient.class);
        Mockito.when(JdbcClient.sendRequest(any())).thenReturn(result);

        String callResult = demoService.callRemote("something");
        assertEquals("fail", callResult);
    }
}

这里的主要用法就是 PowerMockito.mockStatic 这个。但是要结合之前的两个注解,@RunWith(PowerMockRunner.class) @PrepareForTest({JdbcClient.class}) 这个使用才有效

就写这两个场景吧。后续用到比较好的场景再补充,也欢迎大家提供更多使用场景一起学习学习。



Tags:Mock测试   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
在真实的测试当中,并不能所有的逻辑都可以自己控制,因此有了mock测试。今天就结合场景来讲一下怎么做mock测试。适合对象:初次尝试集成和使用mockito进行单元测试的开发同学 Mo...【详细内容】
2020-08-06  Tags: Mock测试  点击:(62)  评论:(0)  加入收藏
▌简易百科推荐
近日只是为了想尽办法为 Flask 实现 Swagger UI 文档功能,基本上要让 Flask 配合 Flasgger, 所以写了篇 Flask 应用集成 Swagger UI 。然而不断的 Google 过程中偶然间发现了...【详细内容】
2021-12-23  Python阿杰    Tags:FastAPI   点击:(6)  评论:(0)  加入收藏
文章目录1、Quartz1.1 引入依赖<dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.3.2</version></dependency>...【详细内容】
2021-12-22  java老人头    Tags:框架   点击:(11)  评论:(0)  加入收藏
今天来梳理下 Spring 的整体脉络啦,为后面的文章做个铺垫~后面几篇文章应该会讲讲这些内容啦 Spring AOP 插件 (了好久都忘了 ) 分享下 4ye 在项目中利用 AOP + MybatisPlus 对...【详细内容】
2021-12-07  Java4ye    Tags:Spring   点击:(14)  评论:(0)  加入收藏
&emsp;前面通过入门案例介绍,我们发现在SpringSecurity中如果我们没有使用自定义的登录界面,那么SpringSecurity会给我们提供一个系统登录界面。但真实项目中我们一般都会使用...【详细内容】
2021-12-06  波哥带你学Java    Tags:SpringSecurity   点击:(18)  评论:(0)  加入收藏
React 简介 React 基本使用<div id="test"></div><script type="text/javascript" src="../js/react.development.js"></script><script type="text/javascript" src="../js...【详细内容】
2021-11-30  清闲的帆船先生    Tags:框架   点击:(19)  评论:(0)  加入收藏
流水线(Pipeline)是把一个重复的过程分解为若干个子过程,使每个子过程与其他子过程并行进行的技术。本文主要介绍了诞生于云原生时代的流水线框架 Argo。 什么是流水线?在计算机...【详细内容】
2021-11-30  叼着猫的鱼    Tags:框架   点击:(21)  评论:(0)  加入收藏
TKinterThinter 是标准的python包,你可以在linx,macos,windows上使用它,你不需要安装它,因为它是python自带的扩展包。 它采用TCL的控制接口,你可以非常方便地写出图形界面,如...【详细内容】
2021-11-30    梦回故里归来  Tags:框架   点击:(26)  评论:(0)  加入收藏
前言项目中的配置文件会有密码的存在,例如数据库的密码、邮箱的密码、FTP的密码等。配置的密码以明文的方式暴露,并不是一种安全的方式,特别是大型项目的生产环境中,因为配置文...【详细内容】
2021-11-17  充满元气的java爱好者  博客园  Tags:SpringBoot   点击:(25)  评论:(0)  加入收藏
一、搭建环境1、创建数据库表和表结构create table account(id INT identity(1,1) primary key,name varchar(20),[money] DECIMAL2、创建maven的工程SSM,在pom.xml文件引入...【详细内容】
2021-11-11  AT小白在线中  搜狐号  Tags:开发框架   点击:(29)  评论:(0)  加入收藏
SpringBoot开发的物联网通信平台系统项目功能模块 功能 说明 MQTT 1.SSL支持 2.集群化部署时暂不支持retain&will类型消 UDP ...【详细内容】
2021-11-05  小程序建站    Tags:SpringBoot   点击:(55)  评论:(0)  加入收藏
相关文章
    无相关信息
最新更新
栏目热门
栏目头条