简介
这是一个仿照Mock.js语法的Java语言使用的假数据生成工具框架。 部分方法与类介绍详细可查看JavaDoc文档:JavaDoc文档
此框架中不仅仅只可以作为假数据获取用,还有一些比较实用的工具类可以拿来单独使用。
*工具类介绍:工具类介绍
当前版本:v1.2
最低JDK版本:JDK8
以下介绍的版本:v1.2 (第一版)
※ 版本更新内容与预期更新计划详见于文档末尾 : 更新公告
使用方法
安装
在maven项目下,从pom.xml中导入以下地址(仅以最新版本作为示例):
<dependency>
<groupId>io.gitee.ForteScarlet</groupId>
<artifactId>mock.java</artifactId>
<version>1.2</version>
</dependency>
使用
相信使用过Mock.js的各位大佬应该知道,在使用Mock.js的时候是用的JSON格式的参数。 但是,Java可是没法直接识别JSON的啊! 所以,我们采用最接近JSON格式的方式:Map集合。
简单来说,就是将一个类的字段根据Mock.js那样的key-value的键值对转化为一个Map<String, Object>对象就好了!我习惯将这种Map对象称为 字段映射表 。
而且作为Java语言,数据类型是必须要多加考虑的问题。我在获取值的时候已经尽可能的增加了容错率,但是还是需要您注意数据类型的问题,请尽可能不要犯下将一个字符串赋值给整数这类难以防范的错误..
或许感觉上比JSON格式的使用要麻烦一些,但是这也是没有办法的事情嘛!假如您有更好的代替方式,希望您能告诉我 :)
框架中的一些常见"角色"
参数解析器/任务分配器(ParameterParser)
负责对用户传入的字段映射(Map集合)进行解析并分配解析任务。
也可以将其理解为 任务分配器 。
字段解析器(FieldParser)
接收任务分配器分配的任务并对字段和其映射进行解析,并取得字段值获取器(FieldValueGetter)。
字段值获取器(FieldValueGetter)
使用字段值的setter方法和字段值获取方法执行者(Invoker)对某个字段进行赋值。
字段值获取方法执行者(Invoker)
通过执行一个某种方法得到一个结果。用于获取字段的值。
假对象(MockObject)
通过Mock.get(Class clz)方法获取到的返回值,用于获取假对象数据。
设置字段映射的方式:
1·创建对象字段与随机值语法的映射关系(Map<String , Object> 类型的键值对)
创建的这个Map,Key值代表了映射的字段名,value值代表了映射语法 由于这毕竟与弱引用类型语言不同,所以在设置映射的时候请务必注意字段的数据类型。
Map<String, Object> map = new HashMap<>();
2·添加字段映射
字段映射中,value值所用到的 @函数 可以从 JavaDoc文档 中查阅[MockUtil]类中的方法,MockUtil中的全部方法均可作为 @函数 出现在value值中。
再次提醒,请务必注意对应好字段的字段类型
map.put("age","@age");
map.put("list|2-3","@title");
map.put("user","@name");
......
key值中,有三种写法:
仅有字段映射、字段映射与整数部分区间参数、字段映射、整数部分区间参数与小数部分区间参数。
例如如下这么两个字段映射:
map.put("money1|10-40.2-4" , 0);
map.put("money2|10-40.2" , 0);
其中,字段名与区间参数之间的分割符为 | 符号,左边为字段名,右半边为区间参数。
区间参数中,整数部分与小数部分用 . 符-号分割,左半边为整数部分区间参数,右半边为小数部分区间参数。
//假设以下字段映射的是User类
Map<String, Object> map = new HashMap<>();
map.put("age1" , "@age");
map.put("age2" , 15);
map.put("age3" , new Integer(){1,2,3,4});
map.put("name1" , "@name");
map.put("name2" , "@title(2)");
map.put("name3" , "这是一个名字");
//下面三个email字段的参数,如果是中文,必须放在单引号或双引号中才会生效,英文不受限制
map.put("email1" , "@email('这是中文')");
map.put("email2" , "@email('this is english')");
map.put("email3" , "@email(this is english)");
//下面的friend字段的字段类型是一个Friend类,friendMap是对friend字段的映射,也就是嵌套映射
//此friendMap的映射无需单独进行记录
map.put("friend" , friendMap);
//记录映射
Mock.set(User.class, map);
//User类的映射被直接记录,可以获取
MockObject<User> userMockObject = Mock.get(User.class);
//Friend类的映射以嵌套的形式被记录过了,可以直接获取
MockObject<Friend> friendMockObject = Mock.get(Friend.class);
//age为一个Integer类型的字段,等同于使用了@integer(2,4)函数
map.put("age|2-4" , 0);
//money为一个Double类型,等同于使用了@doubles(2,4)函数
map.put("money|2-4" , 0);
//age为一个Integer类型的字段
map.put("age|2-4" , new Integer[]{1,2,3});
map.put("age|2" , new Integer[]{1,2,3});
map.put("age" , new Integer[]{1,2,3});
map.put("list|2-6" , "@title");
map.put("age|10-40" , 2);
// money为一个Double类型的字段,此映射等同于使用了@doubles(2,4,2,4)函数
map.put("money|2-4.2-4" , 0);
// money为一个Double类型的字段,此映射等同于使用了@doubles(2,4,2)函数
map.put("money|2-4.2" , 0);
3·获取假字段封装对象
通过Mock的get方法获取一个已经添加过映射记录的数据
//映射表尽可能是Sting,Object类型的
Map<String, Object> map = new HashMap<>();
//添加一个映射
map.put("age|10-40" , 2);
//记录类的映射
//1、使用javaBean封装
Mock.set(User.class , map);
//2、或者直接使用Map类型,不再需要javaBean的class对象,但是需要指定一个映射名
Mock.set("userMap", map);
//已经记录过User类的映射,获取封装类
//1、如果是使用的javaBean记录的,使用javaBean获取
MockObject<User> mockObject = Mock.get(User.class);
//2、或者你之前是使用map记录的,使用记录时保存的映射名获取
//注:MockMapObject 对象实现了MockObject接口
MockMapObject mockMapObject = Mock.get("userMap");
Optional<T> get();
获取一个结果,并使用Optional类进行封装。
T getOne();
获取一个结果
List<T> getList(int num);
获取指定数量的多个结果,返回List集合
List<R> getList(int num , Function<T, R> mapper);
获取指定数量的多个结果,并根据给定规则进行转化,返回List集合
Set<T> getSet(int num);
获取指定数量的多个结果,返回Set集合
Set<R> getSet(int num , Function<T, R> mapper);
获取指定数量的多个结果,并根据给定规则进行转化,返回Set集合
Map<K,V> getMap(int num , Function<T,K> keyMapper , Function <T,V> valueMapper);
获取指定数量的多个结果,并根据给定规则转化为Map集合
自定义@函数
有时候,我提供的MockUtil中的方法可能无法满足您的需求,那么这时候,就需要一个可以对@函数进行扩展、加强的窗口。在v1.1版本中,我添加了这个功能。(这个功能测数量很少,可能会存在很多bug)
1· 获取自定义@函数加载器
//获取@函数加载器
MethodLoader methodLoader = Mock.mockMethodLoader();
函数加载器支持链式加载,也支持一次性加载
链式:
LoadResults loadResults = methodLoader
//添加指定类中的指定方法名的方法
.append(Demo1.class, "testMethod")
//添加指定类中的多个指定方法名的方法
.appendByNames(Demo2.class, new String[]{"method1" , "method2"})
//添加指定类中的多个符合指定正则回则的方法
.appendByRegex(Demo3.class, "[a-zA-Z]+")
//还有很多...敬请查阅API文档
.load();
使用链式加载的时候,请务必记住在结尾使用load()进行加载,否则方法集将无法被加载,而是一直留存在等待区。
非链式:
methodLoader.add(Demo1.class, "testMethod");
通过以上代码可以发现,加载完成后都会有一个 LoadResults 类作为返回值,这个类是在方法加载后的一个加载报告封装类,通过LoadResults 可以获取到刚刚加载的方法谁成功了,谁失败了,失败了的方法为什么失败等信息:
Map<Boolean, Set<Method>> map = loadResults.loadResults();//加载的方法集根据成功与否分组
Set<Method> successMethods = loadResults.loadSuccessResults();//加载成功的方法集
Map<Method, Exception> whyFailMap = loadResults.whyFail();//加载失败的方法以及抛出的异常
int successNum = loadResults.successNums();//成功的个数
int failNum = loadResults.failNums();//失败的个数
假若加载成功后,则此方法便可以直接在映射中直接用@开头作为使用@函数使用了~
引言
如果你觉得,Java没有必要获取假数据,认为我这个所谓"框架"就是一个垃圾,那么何尝不来看看内部自带的几个工具类呢?
(工具类的详细介绍请查看JavaDoc文档 中包路径 com.forte.util.utils 下的类 )
值得一提的:
FieldUtils - 字段相关反射工具类
这是工具类包下最大的一个工具类,至少体积是最大的,用到的次数也是最大的。
这个工具类在对字段进行取值的时候,使用了单层级字段、多层级字段的双缓存机制,不论你是单层字段,还是多层对象嵌套的字段,只需获取一次后,再次获取的效率与直接调用getter方法无异。某天做过5亿数据量的字段值获取测试,经过缓存后获取效率超大幅的提高 。( 关于测试的结果可以查看JavaDoc文档 中此类的文档注释。)
至少它对这个框架来讲用处很大,但是一般情况下来讲,用反射频繁获取字段值的情况并不多见呢..
MockUtil - 随机值获取工具类
这是本框架的核心工具类之一,所有的@函数都是基于动态获取MockUtil中的方法而实现的。( 后期考虑可以使使用者对随机值方法进行横向扩展,即自定义@函数。 ( 已实现 ))
RandomUtil - 随机值、数值区间工具类
它与上面的MockUtil 最大的不同点是它主要是获取一些范围区间内的随机值、随机码、浮点数的小数保留等,更偏向于一种对数据、数值的操作。
SingleFactory - 单例工厂
一个简单的、以乐观锁为原理的线程安全的单例工厂,提供丰富的API来设置、保存、替换单例对象。
留言与评论(共有 0 条评论) |