Stop Hand-Coding Test Data: Generate Java Objects in One Line with Easy Random
This tutorial demonstrates how to use the Easy Random library to automatically generate realistic test data for Java objects, covering basic usage, configuration parameters, field-level customization, and custom randomizers for domain-specific values.
Introduction
Writing test code often involves more effort in preparing test data than implementing business logic. For simple objects like User this is manageable, but complex structures with dozens of fields, nested objects, and collections quickly turn into repetitive boilerplate. Easy Random solves this by generating random Java object instances automatically.
Easy Random Overview
Easy Random is a library for generating random Java objects (including records). It acts as an "object mother" for the JVM. Given a class Person, a random instance is created with:
EasyRandom er = new EasyRandom();
Person person = er.nextObject(Person.class);The EasyRandom#nextObject method generates a random instance of any specified type.
Practical Examples
Environment Setup
Environment: Spring Boot 3.5.0
Add the dependency (test scope):
<dependency>
<groupId>org.jeasy</groupId>
<artifactId>easy-random-core</artifactId>
<version>5.0.0</version>
<scope>test</scope>
</dependency>Domain Classes
public class Person {
private Long id;
private String name;
private Integer age;
private Date birth;
// getters, setters
}
public class Address {
private String province;
private String city;
private String county;
private String street;
// getters, setters
}Quick Start
@Test
public void testRandomPerson() {
EasyRandom er = new EasyRandom();
Person person = er.nextObject(Person.class);
System.err.println(person);
}Output example:
Person [
id=-5106534569952410475,
name=eOMtThyhVNLWUZNRcBaQKxI,
age=-1188957731,
birth=Tue Jun 18 18:54:04 CST 2024
]Default values are often unrealistic (negative age, random strings). Adding an Address field to Person and re-running produces similarly random nested data.
Controlling Data Generation with EasyRandomParameters
EasyRandomParametersis the main configuration entry point. All parameters apply to every field in the object graph:
EasyRandomParameters parameters = new EasyRandomParameters()
.seed(123L) // fixed seed for reproducible runs
.objectPoolSize(100)
.randomizationDepth(3)
.charset(forName("UTF-8")) // charset for all strings/chars
.timeRange(nine, five) // time range
.dateRange(today, tomorrow) // date range
.stringLengthRange(5, 50) // string length bounds
.collectionSizeRange(1, 10) // collection size bounds
.scanClasspathForConcreteTypes(true) // find implementations for abstract/interface fields
.overrideDefaultInitialization(false) // keep default field values
.ignoreRandomizationErrors(true);
EasyRandom easyRandom = new EasyRandom(parameters);Field-Specific Customization
Override specific fields using predicates:
@Test
public void testRandomPersonByParameters() {
EasyRandomParameters parameters = new EasyRandomParameters();
parameters.overrideDefaultInitialization(false);
parameters.stringLengthRange(3, 8);
parameters.randomize(f -> f.getName().equals("age"), new IntegerRangeRandomizer(1, 120));
EasyRandom er = new EasyRandom(parameters);
Person person = er.nextObject(Person.class);
System.err.println(person);
}Output:
Person [
id=0,
name=eOMtTh,
age=60,
birth=Tue Jun 18 18:54:04 CST 2024,
address=Address [
province=yhVNLWU,
city=ZNRc,
county=BaQKxI,
street=yedUsFw
]
]Exclude a nested field:
parameters.excludeField(FieldPredicates.named("city"));Custom Randomizer for Domain-Specific Values
Default string generation only produces random letters. Implement AbstractRandomizer<String> for meaningful values:
public class ProvinceRandomizer extends AbstractRandomizer<String> {
private static final String[] PROVINCES = {
"北京市", "天津市", "河北省", "山西省", "内蒙古自治区", "辽宁省",
"吉林省", "黑龙江省", "上海市", "江苏省", "浙江省", "安徽省",
"福建省", "江西省", "山东省", "河南省", "湖北省", "湖南省",
"广东省", "广西壮族自治区", "海南省", "重庆市", "四川省", "贵州省", "云南省",
"西藏自治区", "陕西省", "甘肃省", "青海省", "宁夏回族自治区",
"新疆维吾尔自治区", "香港特别行政区", "澳门特别行政区", "台湾省"};
public ProvinceRandomizer() { super(); }
public ProvinceRandomizer(long seed) { super(seed); }
@Override
public String getRandomValue() {
int index = random.nextInt(PROVINCES.length);
return PROVINCES[index];
}
}Apply it to the province field of Address:
@Test
public void testRandomPersonByParameters() {
EasyRandomParameters parameters = new EasyRandomParameters();
// ... other config
parameters.randomize(named("province").and(inClass(Address.class)), new ProvinceRandomizer());
EasyRandom er = new EasyRandom(parameters);
Person person = er.nextObject(Person.class);
System.err.println(person);
}Output now includes a real province name:
Person [
id=0,
...
address=Address [
province=福建省,
...
]
]Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
