前言
在日常的测试中,我们经常需要提前准备一大堆测试数据,用来验证业务逻辑。当然对于简单的数据类型完全可以通过 JDK自带的Random类来实现。但是对于一个比较复杂的类,或者参数的格式有特殊要求的时候,Random?就不适用了,这个时候就需要借助一些能够生成测试数据的框架。
相关框架
我在实际调研中,找到了 2个在个人看来还不错的生成框架,他们分别是:
JmockData
Java-Faker
下面我将一一介绍这些框架的优缺点以及适用场景。话不多说,直接开始撸代码。
JmockData
首先出场的是 JmockData框架,它是官方定义如下:
一款实现模拟JAVA类型或对象的实例化并随机初始化对象的数据的工具框架。
依赖
<dependency> <groupId>com.github.jsonzou</groupId> <artifactId>jmockdata</artifactId> <version>4.2.0</version> </dependency> |
基础类型数据生成
@Test public void testBaseType(){ // 基础数据类型 System.out.println(JMockData.mock(byte.class)); System.out.println(JMockData.mock(int.class)); System.out.println(JMockData.mock(long.class)); System.out.println(JMockData.mock(double.class)); System.out.println(JMockData.mock(float.class)); System.out.println(JMockData.mock(String.class)); System.out.println(JMockData.mock(BigDecimal.class)); // 基础数据类型的数组 System.out.println(JMockData.mock(byte[].class)); System.out.println(JMockData.mock(int[].class)); System.out.println(JMockData.mock(long[].class)); System.out.println(JMockData.mock(double[].class)); System.out.println(JMockData.mock(float[].class)); System.out.println(JMockData.mock(String[].class)); System.out.println(JMockData.mock(BigDecimal[].class)); } |
运行结果
0 2610 3401 8582.18 7194.44 5Xu7 9051.92 [B@7fbe847c [I@41975e01 [J@c2e1f26 [D@dcf3e99 [F@6d9c638 [Ljava.lang.String;@7dc5e7b4 [Ljava.math.BigDecimal;@1ee0005 |
JavaBean类型数据生成
/** * java bean 测试 */ @Test public void testJavaBean(){ Person mock = JMockData.mock(Person.class); System.out.println(mock); } |
运行结果
Person[address=RrayfQIK,age=5863,idCard=SDn,name=j] |
这里可以看到,使用JMockdata.mock(xx.class);可以很容易的生成一个JavaBean。框架通过反射,在底层遍历获得类的属性与类型,然后填充数据。
但是与此同时,大家也发现了,虽然我们可以的的确确的生成了一个Person类,也给它的每个属性都填充了值,但是生成的数据只是根据类型简单生成的,比如age字段被填充的是5863。如果数据有现实含义,没有规则的随机就很容易出现乌龙。
要解决这个问题,我们就要限制随机数据的范围,可以通过它的配置功能实现。
使用随机配置
@Test public void testJavaBeanWithConfig() { MockConfig mockConfig = new MockConfig() .subConfig("age") // 设置 int 的范围 .intRange(1, 100) .subConfig("email") // 设置生成邮箱正则 .stringRegex("[a-z0-9]{5,15}\\@\\w{3,5}\\.[a-z]{2,3}") .globalConfig(); Person mock = JMockData.mock(Person.class, mockConfig); System.out.println(mock); } |
运行结果
Person[address=hXttj2s,age=2,email=w14hnn@UvFB9.kt,idCard=V5bBdX,name=KM8] |
可以看到age跟email已经正常了,可以通过他强大的配置功能对于数据进行生成的限制,但是你也发现了,对于一些有简单边界的数据,这样做可以,否则就像address、name这样的数据,很难通过简单规则去生成。
而对于有现实意义的数据生成,可以使用Java-Faker框架。
Java-Faker
依赖
<dependency> <groupId>com.github.javafaker</groupId> <artifactId>javafaker</artifactId> <version>1.0.2</version> </dependency> |
数据生成
@Test public void testRandomName() { Faker faker = new Faker(); final Name name = faker.name(); System.out.println("firstName : " + name.firstName()); System.out.println("username : " + name.username()); System.out.println("bloodGroup : " + name.bloodGroup()); System.out.println("suffix : " + name.suffix()); System.out.println("title : " + name.title()); System.out.println("lastName : " + name.lastName()); System.out.println("nameWithMiddle : " + name.nameWithMiddle()); System.out.println("fullName : " + name.fullName()); System.out.println("name : " + name.name()); System.out.println("prefix : " + name.prefix()); } |
生成结果
firstName : Hollis username : cristy.white bloodGroup : O- suffix : Sr. title : Product Implementation Specialist lastName : Johnston nameWithMiddle : Alesia Hagenes Kiehn fullName : Dr. Pat Marvin name : Ms. Jamal Rau prefix : Mr. |
可以看到Java-Faker生成数据特别的方便,基本格式如下:
Faker faker = new Faker(); final Xx xx = faker.xx(); xx.yyyy; |
步骤:
1.创建Faker对象;
2.通过Faker对象获得要生成的实体对象;
3.调用实体对象获得对于生成的部分。
这里的实体对象,对应上面的name,也就说我们要生成姓名相关的数据,拿到实体对象后还可以只获得其中的部分数据,比如姓名中的姓或名,还有前缀,甚至血型,可以说是非常全面。
而且Java-Faker支持的实体对象特别的多,如下:
从身份证到姓名再到地址、动物、书籍、头像、职位等等,基本上覆盖了我们生活中的方方页面。
另外,Java-Faker更贴心的是帮我们实现了国际化,可能刚才看了姓名的例子,有些朋友觉得这个框架好看但不好用,就拿生成姓名来说,生成都是Johnston、Tom、Kiwi之类英文名,在国内很少用到这些数据。其实jJava-Faker已经考虑到这个问题。而且只要改一行代码就可以了。
修改后的代码
// 原代码 Faker faker = new Faker(); // 新代码 Faker faker = new Faker(Locale.CHINA); final Name name = faker.name(); System.out.println("firstName : " + name.firstName()); System.out.println("username : " + name.username()); System.out.println("bloodGroup : " + name.bloodGroup()); System.out.println("suffix : " + name.suffix()); System.out.println("title : " + name.title()); System.out.println("lastName : " + name.lastName()); System.out.println("nameWithMiddle : " + name.nameWithMiddle()); System.out.println("fullName : " + name.fullName()); System.out.println("name : " + name.name()); System.out.println("prefix : " + name.prefix()); |
生成结果
firstName : 熠彤 username : 烨霖.龙 bloodGroup : A- suffix : IV title : Investor Division Engineer lastName : 范 nameWithMiddle : 胡思 fullName : 孟鸿涛 name : 黎航 prefix : Miss |
只需要,把之前的Fakerfaker=newFaker();改成Fakerfaker=newFaker(Locale.CHINA);即可。如果你想生成其它国家的内容也是可以的,Java-Faker支持的国家如下:
总结
JmockData
个人感觉它是 plus版的Random类,方便简单的按类型生成数据,也可以自己给定配置与规则去生成,缺点,上文也说了,生成的数据没有太多实际意义,简单数据还好,如果像姓名、地址等有现实意义的数据,就不太合适了。
Java-Faker
Java-Faker其实是迁移自ruby中大名鼎鼎的Faker。很多语言都有他的对应迁移,比如python、java。所以数据量和功能是很完善并且经过考验的,使用起来也很方便。实际工作中,可以优化使用。如果要说缺点,个人觉得他有些地方国际化的并不全面,比如车牌、身份证之类的。如果对于这些数据有比较严格的要求。
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理