之前为了生成大量测试数据写了一些工具。现在发现JavaFaker非常强大,可以生成各种类型数据,包括地址、流行文化等,且支持
locale
国际化。本文带你学习JavaFaker,通过示例展示如何使用
FakeValueService
和Faker
类,后面再介绍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 生成特定区域数据。