1. 概述

JavaFaker 是一个用于生成测试、假数据的 Java 库,可以生成各种类型的数据,如地址、姓名、电话号码、文件等等。

本文我们将学习如何使用JavaFaker生成假数据。首先介绍 Faker 类和 FakeValueService,然后再介绍如何本地化,以适配不同的国家和地区。

最后,我们将讨论数据的唯一性。为了测试 JavaFaker 的类,我们将使用正则表达式

2. Maven 依赖

需要添加下面的 Maven 依赖:

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

对于 Gradle 用户,添加下面的内容到 build.gradle 中:

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

3. FakeValueService

FakeValueService 类提供了 **生成随机序列**,以及解析与本地化设置相关的 .yml 文件的方法。

在本节中,我们将介绍 FakerValueService 提供的一些有用方法。

3.1. Letterify, Numerify, 和 Bothify

  • Letterify 用于生成 随机的字母字符序列
  • Numerify 只生成数字序列
  • Bothify 是这两者的结合,可以创建随机的字母数字序列,对于模拟像ID字符串这样的东西非常有用。

FakeValueService 需要2个参数 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对象,语言设置为en-GB,使用 bothify 方法生成一个唯一的假的Gmail邮箱

其中,“?”表示为随机字母,"#" 表示随机数字。最后我们通过正则表达式验证输出是否正确。

3.2. 正则化

类似地,regexify 方法根据提供的正则表达式生成随机序列

@Test
public void givenValidService_whenRegexifyCalled_checkPattern() throws Exception {

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

    // 生成了一个长度为10的包含小写字母和数字的字符串
    String alphaNumericString = fakeValuesService.regexify("[a-z1-9]{10}");
    // 检查结果
    Matcher alphaNumericMatcher = Pattern.compile("[a-z1-9]{10}").matcher(alphaNumericString);
 
    assertTrue(alphaNumericMatcher.find());
}

上面的代码生成了一个长度为10,包含小写字母和数字的字符串

4. Faker 类

下面我们将学习如何使用 Faker 类生成假数据

Faker faker = new Faker();

String streetName = faker.address().streetName();
String number = faker.address().buildingNumber();
String city = faker.address().city();
String country = faker.address().country();

System.out.println(String.format("%s\n%s\n%s\n%s",
  number,
  streetName,
  city,
  country));

上面,我们使用 Faker的 Address 对象来生成一个随机的地址

生成结果如下:

3188
Dayna Mountains
New Granvilleborough
Tonga

We can see that the data has no single geographical location since we didn’t specify a locale. To change this, we’ll learn to make the data more relevant to our location in the next section.

类似的,我们还可创建其他的数据类型,例如:

  • Business
  • Beer
  • Food - 食物
  • PhoneNumber - 电话号码

完整列表请参考文档

5. 本地化

我们还可以通过 设置语言区域使生成的数据更加真实和易读。例如,下面我们创建2个 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());
}

上面,我们看到两个带有区域设置的Fakers匹配了它们国家的邮政编码的正则表达式。

如果传递给Faker的区域设置不存在,Faker将抛出一个LocaleDoesNotExistException

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

6. 唯一性

虽然 JavaFaker 看似生成的是随机数据,但其实不能保证唯一性

JavaFaker支持种子化其伪随机数生成器(PRNG),以RandomService的形式提供重复方法调用的确定性输出。

简单来说,伪随机性是一个看起来随机但实际不是随机的过程。

我们可以通过创建两个相同种子的Fakers来了解这如何工作:

@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());
}

上面的代码从两个 不同的faker 返回相同的名字。

7. 总结

在本教程中,我们探索了JavaFaker库以生成看起来真实的假数据。我们还涵盖了两个有用的类:Faker类和FakeValueService类。

我们探索了如何使用区域设置来生成特定位置的数据。

最后,我们讨论了生成的数据只看起来随机,数据的唯一性并不能保证。

最后文中的代码可以在GitHub上找到。


« 上一篇: 使用SnakeYAML解析YAML
» 下一篇: Java MQTT客户端