如何优雅Mock一个对象?

366 阅读4分钟

开发背景

验证之前开发的的ES-ORM(ES-ORM),需要造很多数据来验证,比如指定长度的字符串,随机长度的字符串,指定范围的数字。。。等等各式各样的随机数据。基于此开发了一个小工具,专门用来Mock对象,使用起来及其简单。

快速入门

1. 准备你要Mock的类。

这一步并且指明你要Mock哪些字段,Mock的规则是什么?

@Data
public class Student {
    @RandomString(minLen = 5, maxLen = 6, charTypes = {UPPER_CASE, NUMBER, LOWER_CASE})
    private String name;
    @RandomLong(min = 1, max = 3)
    private long id;
    @RandomInt(min = 1, max = 5)
    private int age;
    @RandomDouble(min = 1, max = 5)
    private double score;
    @RandomTime(minTime = "2023/01/01 00:00:00", maxTime = "2023/05/06 00:00:00", timePattern = "yyyy/MM/dd HH:mm:ss")
    private LocalDateTime birthDay;
    @RandomList(fixedSize = 1, strFixedLen = 10, charTypes = {UPPER_CASE, NUMBER, LOWER_CASE})
    private List<String> strList;
    @RandomList(fixedSize = 1, intMin = 1, intMax = 5)
    private List<Integer> intList;
    @RandomList(fixedSize = 1, longMin = 2, longMax = 20)
    private List<Long> longList;
    @RandomList(fixedSize = 1, doubleMin = 10, doubleMax = 30)
    private List<Double> doubleList;
    @RandomBoolean
    private boolean isMale;
    @RandomEntity
    private School school;
}

@Data
public class School {
    @RandomString(fixedLength = 3, charTypes = {CharType.LOWER_CASE, CharType.UPPER_CASE})
    private String name;
    @RandomEntity
    private Class clazz;
}

@Data
public class Class {
    @RandomInt(min = 1, max = 12)
    private Integer classNo;
}
  1. @RandomString,它可以指定的属性是 : minLen, maxLen, fixedLen, charTypes

假如你想要一个长度2-5,只包含数字的随机字符串,你应该设置 minLen = 2, maxLen = 5, charTypes = {NUMBER},

假如你想要一个长度固定为3,包含大写字母+小写字母+数字的随机字符串,你应该设置 fixLen = 3, chatType = {NUMBER, UPPER_CASE, LOWER_CASE}

2,@RandomInt,产生一个随机整数

3,@RandomDouble,产生一个随机小数

4,@RandomLong,产生要给随机Long

5,@RandomTime,产生一个随机时间(该随机时间 <= maxTime, >= minTime),所以你需要指定minTime, maxTime, 以及minTime 和 maxTime 共同的时间格式pattern

6, @RandomList, 假如你希望产生一个 长度为5的字符串List,然后里面的字符串固定长度为3,只包含数字,你需要设置, fiexSize = 5, strFixedLen = 3 , charTypes = {NUMBER}

7, @RandomBoolean, 随机产生true or false

8, @RandomEntity,标记这个属性是一个自定义对象类型,该自定义对象的类上也需要添加这些注解

2. 直接调用 MockService.mock()即可!

public static void main(String[] args) {
    for (int i = 0; i < 10; i++) {
        Student student = MockService.mock(Student.class);
        System.out.println(student);
    }
}

最后看一下结果。

Student(name=HXG8g, id=3, age=1, score=3.606763211833847, birthDay=2023-01-19T18:18:22.883, strList=[9aKYqhPAKq], intList=[2], longList=[12], doubleList=[23.943750862913166], isMale=true, school=School(name=daQ, clazz=Class(classNo=7)))
Student(name=RpH8xR, id=1, age=2, score=3.101798853708893, birthDay=2023-03-11T00:11:14.262, strList=[rgjfMYtL2J], intList=[2], longList=[6], doubleList=[28.138840442212718], isMale=false, school=School(name=xcj, clazz=Class(classNo=6)))
Student(name=E0XGLa, id=2, age=4, score=1.676280810590161, birthDay=2023-02-10T04:08:58.806, strList=[B11H48jwqk], intList=[2], longList=[3], doubleList=[12.197099452142233], isMale=false, school=School(name=efD, clazz=Class(classNo=7)))
Student(name=zCtB1Q, id=3, age=5, score=2.315336377465367, birthDay=2023-02-13T12:34:15.793, strList=[lPi7j0G6Gu], intList=[4], longList=[8], doubleList=[24.688430764090594], isMale=true, school=School(name=Cbw, clazz=Class(classNo=6)))
Student(name=9wrGRY, id=2, age=5, score=1.4877416213183974, birthDay=2023-02-17T23:05:43.411, strList=[MV3nza24AQ], intList=[4], longList=[11], doubleList=[13.362560199496794], isMale=true, school=School(name=LeN, clazz=Class(classNo=7)))
Student(name=d1zjZ7, id=3, age=1, score=4.336040481687575, birthDay=2023-04-11T04:33:53.933, strList=[WvdSlkizGV], intList=[1], longList=[14], doubleList=[13.614222997576995], isMale=false, school=School(name=hDu, clazz=Class(classNo=4)))
Student(name=eCCW4P, id=2, age=4, score=2.193364734338385, birthDay=2023-03-13T10:55:54.790, strList=[8VI1bImoh3], intList=[5], longList=[17], doubleList=[16.810516235829162], isMale=false, school=School(name=apD, clazz=Class(classNo=9)))
Student(name=XYfSr, id=3, age=1, score=4.082008822514524, birthDay=2023-02-23T02:00:32.364, strList=[0kaQGjyZaF], intList=[5], longList=[3], doubleList=[17.372394991334417], isMale=false, school=School(name=GiI, clazz=Class(classNo=6)))
Student(name=T9iJUq, id=3, age=3, score=1.2048380982136822, birthDay=2023-04-17T03:09:55.259, strList=[ixwEcu1Okr], intList=[3], longList=[4], doubleList=[26.675431261205386], isMale=true, school=School(name=aXi, clazz=Class(classNo=12)))
Student(name=yMzziB, id=1, age=2, score=4.112069072949657, birthDay=2023-01-09T06:34:59.610, strList=[LkIq2wVk3X], intList=[4], longList=[13], doubleList=[16.65229669203731], isMale=true, school=School(name=jjm, clazz=Class(classNo=4)))

使用起来极其简单!

如果你想扩展你自己的Mock逻辑该怎么办?

该工具采用的是 SPI机制扩展。所以你只需要实现 IMockHandler 接口即可。至于实现逻辑可以参考 包 com.hdu.mockService.handler ,最后把你的实现类添加到 META-INFO/com.hdu.mockService.handler.IMockHandler 即可(SPI规范)

源码

gitee.com/K0n9DiKuA/m…