在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
Mock.java使用说明手册简介这是一个仿照Mock.js语法的Java语言使用的假数据生成工具框架。部分方法与类介绍详细可查看JavaDoc文档(推荐先下载下来再看):JavaDoc文档 码云生成的在线javaDoc文档:在线文档 如果存在BUG或者有什么意见、建议,可以通过 issue 进行反馈。 github: github gitee : 码云地址 此框架中不仅仅只可以作为假数据获取用,还有一些比较实用的工具类可以拿来单独使用。 *工具类介绍:工具类介绍 当前版本: 最低JDK版本:JDK8 ※ 版本更新内容与预期更新计划详见于文档末尾 : 更新公告 WIKI文档将会开始转移至WIKI处,转移完成后,此处README中的说明性文档将不再更新并择日删除,替换为简单的介绍与demo示例。 wiki文档:github wiki or gitee wiki 注意未来2.x版本将会使用与1.x版本不同的包路径。如果迭代版本请注意包路径的修改。仅为修改包路径,其余内容不变。如果有2.x的话 友情链接
使用方法Maven在maven项目下,从pom.xml中导入以下地址:
<dependency> <groupId>io.gitee.ForteScarlet</groupId> <artifactId>mock.java</artifactId> <version>${version}</version></dependency> Gradlecompile group: 'io.gitee.ForteScarlet', name: 'mock.java', version: '${version}' Jar使用jar包导入的时候,记得同时把作为依赖的 使用相信使用过Mock.js的各位大佬应该知道,在使用Mock.js的时候是用的JSON格式的参数。但是,Java可是没法直接识别JSON的啊!所以,我们采用最接近JSON格式的方式:Map集合。 简单来说,就是将一个类的字段根据Mock.js那样的key-value的键值对转化为一个Map<String, Object>对象就好了!我习惯将这种Map对象称为 字段映射表 。 而且作为Java语言,数据类型是必须要多加考虑的问题。我在获取值的时候已经尽可能的增加了容错率,但是还是需要您注意数据类型的问题,请尽可能不要犯下将一个字符串赋值给整数这类难以防范的错误.. 或许感觉上比JSON格式的使用要麻烦一些,但是这也是没有办法的事情嘛!假如您有更好的代替方式,希望您能告诉我 :) 设置字段映射的方式:1·创建对象字段与随机值语法的映射关系(Map<String , Object> 类型的键值对)创建的这个Map,Key值代表了映射的字段名,value值代表了映射语法由于这毕竟与弱引用类型语言不同,所以在设置映射的时候请务必注意字段的数据类型。
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); 其中,字段名与区间参数之间的分割符为 | 符号,左边为字段名,右半边为区间参数。 区间参数中,整数部分与小数部分用 . 符号分割,左半边为整数部分区间参数,右半边为小数部分区间参数。
map.put("list|2-6" , "@title"); map.put("age|10-40" , 2);
3·获取假字段封装对象通过Mock的get方法获取一个已经添加过映射记录的数据
//已经记录过User类的映射,获取封装类//1、如果是使用的javaBean记录的,使用javaBean获取MockObject<User> mockObject = Mock.get(User.class);//2、或者你之前是使用map记录的,使用记录时保存的映射名获取//注:MockMapObject 对象实现了MockObject接口MockMapObject mockMapObject = Mock.get("userMap");
// 获取一个结果,并使用Optional类进行封装。Optional<T> get(); // 获取一个结果T getOne(); // 获取指定数量的多个结果,返回List集合List<T> getList(int num); // 获取指定数量的多个结果,并根据给定规则进行转化,返回List集合List<R> getList(int num , Function<T, R> mapper); // 获取指定数量的多个结果,返回Set集合Set<T> getSet(int num); // 获取指定数量的多个结果,并根据给定规则进行转化,返回Set集合Set<R> getSet(int num , Function<T, R> mapper); ```java // 获取指定数量的多个结果,并根据给定规则转化为Map集合Map<K,V> getMap(int num , Function<T,K> keyMapper, Function<T,V> valueMapper);``` 自定义@函数有时候,我提供的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();
非链式: methodLoader.add(Demo1.class, "testMethod"); 通过以上代码可以发现,加载完成后都会有一个 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();//失败的个数 假若加载成功后,则此方法便可以直接在映射中直接用@开头作为使用@函数使用了~ 注解形式映射1.4版本之后我提供了两个可以使用在字段上的注解: @MockValue使用在类的字段上,参数: /** * 映射值,如果为空则视为无效 */ String value(); /* --- 1.6.0后增加 --- */ /** * 区间参数,如果有值,则代表了字段之前的区间参数。默认没有值 * 例如当字段{@code age} 的注解参数为 {@code param = "10-20"} 的时候, 相当于字段值为 {@code "age|10-20"}。参数中的那个竖线不需要写。写了也会被去除的。 * @since 1.6.0 */ String param() default ""; /** * 参数value的最终类型,在转化的时候会使用beanutils中的工具类 {@link org.apache.commons.beanutils.ConvertUtils}进行类型转化, 默认为String类型。 * @return */ Class<?> valueType() default String.class; 也就是说,假设这个字段叫做: // 其中,${value()} 的最终结果值为通过ConvertUtils进行转化的结果。// 其中,[|${param()}]的存在与否取决于param()里有没有值xxxMap.put("${field_A}[|${param()}]", (${valueType()}) ${value()}) 用来指定此字段的映射值。例如: public class User { // 相当于 ("name", "@cname") @MockValue("@name") private String name; // 相当于 ("age|20-40", 0) @MockValue(value = "0", param = "20-40", valueType = Integer.class) private Integer age; // 省略 getter & setter } @MockArray使用在类的字段上,参数: /** * 数组参数, 必填参数 */ String[] value(); /** * 类型转化器实现类,需要存在无参构造 * 默认转化为字符串,即默认不变 */ Class<? extends ArrayMapper> mapper() default ArrayMapperType.ToString.class; /* --- 1.6.0后增加 --- */ /** * 区间参数,如果有值,则代表了字段之前的区间参数。默认没有值 * 例如当字段{@code age} 的注解参数为 {@code param = "10-20"} 的时候, 相当于字段值为 {@code "age|10-20"}。参数中的那个竖线不需要写。写了也会被去除的。 * @since 1.6.0 */ String param() default ""; 其中,
/** * 给你一个数组长度,返回一个数组实例的function,用于数组的实例化获取 * @return 数组实例获取函数,例如:Integer[]::new; 或者 size -> new Integer[size]; */ IntFunction<T[]> getArrayParseFunction(); /** * 将字符串转化为指定类型 */ T apply(String t); 在对 对于一些比较常见的类型转化,我提供了几个已经实现好的实现类。这些实现类以内部类的形式存在于
例如: public class User { @MockArray(value = {"1", "2", "3"}, mapper = ArrayMapperType.ToInt.class) private int age; // 省略 getter & setter} 使用使用也很简单,我在 /* --- 1.4版本之后增加 --- */ /** * 通过注解来获取映射 */ public static <T> void set(Class<T> objClass); /** * 通过注解来获取映射, 并提供额外的、难以用注解进行表达的映射参数 */ public static <T> void setWithOther(Class<T> objClass, Map<String, Object> other); /** * 通过注解来获取映射 */ public static <T> void reset(Class<T> objClass); /** * 通过注解来获取映射, 并提供额外的、难以用注解进行表达的映射参数 */ public static <T> void resetWithOther(Class<T> objClass, Map<String, Object> other); 注意事项注解优先级假如你在同一个字段上同时使用了两个注解,则会优先使用 额外映射可以发现,4个方法中各有一个方法需要提供额外参数,他会在注解映射创建完毕后进行添加,也就是假如额外参数和字段中有冲突的键,则额外参数的值将会覆盖注解映射值。 映射扫描1.6.0版本后,我更新了映射扫描与映射代理功能。感谢提出建议的朋友。Issue#I1CCMT 在您使用注解形式映射的时候,是否有感觉到每个类都需要使用 对于 /** * 扫描包路径,加载标记了{@link com.forte.util.mapper.MockBean}注解的类。 * * @param classLoader nullable, 类加载器, null则默认为当前类加载器 * @param withOther nullable, 假如扫描的类中存在某些类,你想要为它提供一些额外的参数,此函数用于获取对应class所需要添加的额外参数。可以为null * @param reset 加载注解映射的时候是否使用reset * @param packages emptyable, 要扫描的包路径列表, 为空则直接返回空set * @return 扫描并加载成功的类 */ public static Set<Class<?>> scan(ClassLoader classLoader, Function<Class<?>, Map<String, Object>> withOther, boolean reset, String... packages) throws Exception; 这么多参数?先别怕,我先简单介绍下这些参数:
除了这个方法,我还提供了一些重载方法: /** * {@link #scan(ClassLoader, Function, boolean, String...)}的重载方法 * @see #scan(ClassLoader, Function, boolean, String...) */ public static Set<Class<?>> scan(Function<Class<?>, Map<String, Object>> withOther, boolean reset, String... packages) throws Exception; /** * {@link #scan(ClassLoader, Function, boolean, String...)}的重载方法 * @see #scan(ClassLoader, Function, boolean, String...) */ public static Set<Class<?>> scan(boolean reset, String... packages) throws Exception; /** * {@link #scan(ClassLoader, Function, boolean, String...)}的重载方法, reset默认为false * @see #scan(ClassLoader, Function, boolean, String...) */ public static Set<Class<?>> scan(String... packages) throws Exception; 使用所以一般情况下,你可以直接这么使用: // 扫描两个包Mock.scan("forte.test2.beans", "forte.test1.beans", ...);// 然后直接获取Mock.get(Xxxx.class);// 使用 映射代理1.6.0版本后,我更新了映射扫描与映射代理功能。感谢提出建议的朋友。Issue#I1CCMT 首先看一下Issue上提出的模拟场景: // interface public interface ServiceA{ VoA methodA();}// bean, can with @MockBeanpublic class VoA{ @MockValue("@cname") private String p1;
|
请发表评论