使用JavaFaker生成测试数据

之前为了生成大量测试数据写了一些工具。现在发现JavaFaker非常强大,可以生成各种类型数据,包括地址、流行文化等,且支持locale国际化。

本文带你学习JavaFaker,通过示例展示如何使用FakeValueServiceFaker 类,后面再介绍locale,让生成的数据属于特定地域。

1. 加入依赖包

maven依赖如下:

<dependency>
    <groupId>com.github.javafaker</groupId>
    <artifactId>javafaker</artifactId>
    <version>0.15</version>
</dependency>

gradle 依赖:

compile group: 'com.github.javafaker', name: 'javafaker', version: '0.15'

2. FakeValueService

FakeValueService 提供了生成随机序列方法,和yml文件一样,可以关联locale。本节主要介绍其常用方法。

2.1 Letterify, Numerify, and Bothify方法

Letterify, Numberify, 和 Bothify方法很常用。Letterify生成字母序列, Numberify生成数值序列, Bothify生成字母和数值序列,用于生成特定对象标识。实例FakeValueService 需要有效的 Locale和 RandomService对象

@Test
public void whenBothifyCalled_checkPatternMatches() throws Exception {

    FakeValuesService fakeValuesService = new FakeValuesService(
      new Locale("en-GB"), new RandomService());

    String email = fakeValuesService.bothify("????##@gmail.com");
    Matcher emailMatcher = Pattern.compile("\\w{4}\\d{2}@gmail.com").matcher(email);
 
    assertTrue(emailMatcher.find());
}

上面代码创建 *FakeValueService* 类,指定英国地区并使用 bothify方法生成唯一Gmail地址。?表示随机字母,#表示随机数字。最后使用Matcher类检查生成结果。

2.2 Regexify方法

类似的,regexify方法基于给定正则表达式生成随机序列。

@Test
public void givenValidService_whenRegexifyCalled_checkPattern() throws Exception {

    FakeValuesService fakeValuesService = new FakeValuesService(
      new Locale("en-GB"), new RandomService());

    String alphaNumericString = fakeValuesService.regexify("[a-z1-9]{10}");
    Matcher alphaNumericMatcher = Pattern.compile("[a-z1-9]{10}").matcher(alphaNumericString);
 
    assertTrue(alphaNumericMatcher.find());
}

上面代码生成10个长度的小写字母或数字组成的序列。

3. JavaFaker的 Faker

Faker类可以使用JavaFaker的虚拟数据。本节我们实例化Faker类并使用它生成虚拟数据:

    @Test
    public void testFaker(){
        Faker faker = new Faker(Locale.CHINA);

        Address addr = faker.address();
        String streetName = addr.streetName();
        String number = addr.buildingNumber();
        String city = addr.city();
        String state = addr.state();

        System.out.println(String.format("%s\t%s\t%s\t%s", number, streetName, city, state));
    }

我们使用Faker的地址对象生成随机地址。运行结果:

5011	姜路	西乡县	广西省

这里指定了locale,因此生成中文地址信息。后面还要说明国际化配置。

类似我们还可以生成其他对象,如:

  • Business
  • Beer
  • Food
  • PhoneNumber

4. 介绍 Locale

这里我们介绍如何使用locale,使得生成的数据位于特定位置。下面定义两个不同地区的Faker:

@Test
public void givenJavaFakersWithDifferentLocals_thenHeckZipCodesMatchRegex() {

    Faker ukFaker = new Faker(new Locale("en-GB"));
    Faker usFaker = new Faker(new Locale("en-US"));

    System.out.println(String.format("American zipcode: %s", usFaker.address().zipCode()));
    System.out.println(String.format("British postcode: %s", ukFaker.address().zipCode()));

    Pattern ukPattern = Pattern.compile(
      "([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|"
      + "(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y]" 
      + "[0-9]?[A-Za-z]))))\\s?[0-9][A-Za-z]{2})");
    Matcher ukMatcher = ukPattern.matcher(ukFaker.address().zipCode());

    assertTrue(ukMatcher.find());

    Matcher usMatcher = Pattern.compile("^\\d{5}(?:[-\\s]\\d{4})?$")
      .matcher(usFaker.address().zipCode());

    assertTrue(usMatcher.find());
}

上面代码生成两个不同地区的邮政编码,如果指定的locale不存在,则 Faker 抛出 ***LocaleDoesNotExistException***异常:

@Test(expected = LocaleDoesNotExistException.class)
public void givenWrongLocale_whenFakerInitialised_testExceptionThrown() {
    Faker wrongLocaleFaker = new Faker(new Locale("en-seaWorld"));
}

5. 唯一性

JavaFaker 可以随机生成数据,但不能保证唯一性。 JavaFaker支持伪随机种子,与RandomService形式一样,使得重复方法调用输出一致:

@Test
public void givenJavaFakersWithSameSeed_whenNameCalled_CheckSameName() {

    Faker faker1 = new Faker(new Random(24));
    Faker faker2 = new Faker(new Random(24));

    assertEquals(faker1.name().firstName(), faker2.name().firstName());
}

因此伪随机是一个看似随机但并非随机的过程。上面代码使用相同的种子,生成结果一样。

6. 总结

本文介绍了JavaFaker 生成虚拟数据。主要介绍其中 Faker 类 和 FakeValueService 类;同时也说明如何使用 locale 生成特定区域数据。

上一篇:python faker 工具


下一篇:RedisClient支持Sentinel与Cluster踩坑