日常在写单元测试过程中,如何构造合适的测试数据是比较麻烦并且乏味的。本篇将介绍俩个工具用于生成测试数据,首先介绍Datafaker,此工具用于生成各种常见的测试数据。接着介绍easy-random,用于生成测试对象。最后介绍如何结合这俩个工具生成比较真实的测试对象。
Datafaker
简单的例子,在代码中引入以下jar包
1 2 3 4 5
| <dependency> <groupId>net.datafaker</groupId> <artifactId>datafaker</artifactId> <version>1.2.0</version> </dependency>
|
简单使用
1 2 3 4 5 6 7 8 9 10 11 12
| import net.datafaker.Faker;
Faker faker = new Faker();
String name = faker.name().fullName();
String firstName = faker.name().firstName();
String lastName = faker.name().lastName();
String streetAddress = faker.address().streetAddress();
|
结合locale生成符合当前时区的测试数据,同时设置对应的随机值,可以保证每次生成的数据都一致
1 2 3
| Faker faker = new Faker(Locale.SIMPLIFIED_CHINESE,new Random(0)); String name = faker.name().fullName(); System.out.println(name);
|
生成集合测试数据
1 2 3
| List<String> names = new FakeCollection.Builder<String>() .suppliers(() -> faker.name().firstName(), () -> faker.name().lastName()) .minLen(3) .maxLen(5).build().get();
|
还有更多的用法,比如自定义数据,测试文件构建等等,可以参考官方文档。
easy-random
这个主要用来随机生成对象
简单例子
1 2 3 4 5 6 7 8 9 10
| EasyRandom easyRandom = new EasyRandom(); Person person = easyRandom.nextObject(Person.class);
@Data public class Person {
private int age;
private String name; }
|
使用上面方式生成的数据比较随意,不一定符合测试数据的要求,可以通过自定义填充方式,来生成合适的数据。使用方式如下,实现Randomizer来自定义生成测试数据的方式。
1 2 3 4 5 6 7 8 9
| public class NameRandomizer implements Randomizer<String> {
private List<String> names = Arrays.asList("John", "Brad", "Tommy");
@Override public String getRandomValue() { return names.get(new Random().nextInt(2)); } }
|
可以通过注解或者自定义编码来使用上面自定义的数据生成方式。下面介绍编码的方式
1 2 3 4 5 6 7
| EasyRandomParameters parameters = new EasyRandomParameters() .randomize(FieldPredicates.named("name").and(FieldPredicates.ofType(Integer.class)).and(FieldPredicates.inClass(Person.class)), new NameRandomizer()) .build();
EasyRandom easyRandom = new EasyRandom(easyRandomParameters); Person person = easyRandom.nextObject(Person.class); System.out.println(person);
|
通过上面生成的测试数据相对比较符合要求。这个工具包已经内置了很多Randomizer ,具体可以在org.jeasy.random.randomizers包下查找合适的。除了上面的方式,还可以结合bean validation来生成合适的测试数据,例子如下
首先需要引入如下的包
1 2 3 4 5
| <dependency> <groupId>org.jeasy</groupId> <artifactId>easy-random-bean-validation</artifactId> <version>${latest.version}</version> </dependency>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| public class Person {
private String name;
@javax.validation.constraints.Size(min = 5, max = 10) private List<String> nickNames;
@javax.validation.constraints.Past private Date birthDate;
}
LocalDate today = LocalDate.now(); EasyRandomParameters parameters = new EasyRandomParameters().collectionSizeRange(1, 4) .randomize(FieldPredicates.named("birthDate").and(FieldPredicates.inClass(Person.class)), new LocalDateRangeRandomizer(today, today.plusYears(10))); EasyRandom easyRandom = new EasyRandom(parameters);
Person person = easyRandom.nextObject(Person.class);
assertThat(person.names.size()).isBetween(5, 10); assertThat(person.birthDate).isAfterOrEqualTo(today);
|
上面的例子同时也验证对象上的注解优先于全局注册的Randomizer
结合使用
前面的例子可以看出,datafaker能够生成比较真实的测试数据,easy-random能够快速填充对象。可以通过以下方式结合使用
1 2 3 4 5 6 7
| Faker faker = new Faker(Locale.SIMPLIFIED_CHINESE); EasyRandomParameters easyRandomParameters = new EasyRandomParameters() .randomize(FieldPredicates.named("name"),()->faker.name().name()) .randomize(FieldPredicates.named("age"),()->new Random().nextInt(100)); EasyRandom easyRandom = new EasyRandom(easyRandomParameters); Person person = easyRandom.nextObject(Person.class); System.out.println(person);
|