Dummy4j is an easy to use dummy data generator library for Java, designed for extensibility.
Dummy4j can be used in all projects using Java 8+.
Add the following dependency to your pom.xml
:
<!-- https://mvnrepository.com/artifact/dev.codesoapbox/dummy4j -->
<dependency>
<groupId>dev.codesoapbox</groupId>
<artifactId>dummy4j</artifactId>
<version>0.11.0</version>
</dependency>
Now you can start using Dummy4j:
Dummy4j dummy = new Dummy4j();
String randomCountry = dummy.nation().country();
The default configuration of Dummy4j uses a file-based definition provider which reads data definitions from .yml
files inside the resources/dummy4j
folder. Additionally, the default locale is en
.
Reference documentation for Dummy4j is available at:
https://daniel-frak.github.io/dummy4j
API documentation for Dummy4j is available at:
https://javadoc.io/doc/dev.codesoapbox/dummy4j
Generating dummy data greatly simplifies development and testing of software. While many such generators exist, none of those for Java seem to support easy extensibility, which is crucial for many use cases.
While the ideas behind Dummy4j were first presented as a proposal for Java Faker, it turned out that it would be easier to write an entirely new library.
Dummy4j focuses on ease of use, clean code and effortless extensibility, while still taking inspiration from Ruby's Faker gem.
Not all data is going to be useful to the general public and not all data can be publicly shared due to company policies. Therefore, it is imperative a dummy data library allows for easy and maintainable extension of its data definitions.
Furthermore, edge cases may exist where the functionality of the library must be altered. It is easy to imagine wanting to store data definitions in a central private repository from which the library would load them during instantiation. The classes themselves must, therefore, be clean, well documented and extensible.
While you can easily add your own dummy data definitions, the following are available out of the box:
- Name
- Nation (since 0.2.0)
- Address
- Lorem
- Date and Time (since 0.4.0)
- Identifier (since 0.5.0)
- Education (since 0.3.0)
- Book (since 0.2.0)
- Research Paper (since 0.2.0)
- Sci-fi
- Color (since 0.4.0)
- Numerals (since 0.4.0)
- Medical (since 0.4.0)
- Nato Phonetic Alphabet (since 0.4.0)
- Internet (since 0.5.0)
- Finance (since 0.6.0)
- Business (since 0.10.0)
Dummy4j dummy = new Dummy4j();
String fullName = dummy.name().fullName();
String researchPaperTitle = dummy.researchPaper().title();
String sixSentenceParagraph = dummy.lorem().paragraph(6);
String romanNumeralsBetweenOneAndFifteen = dummy.numerals().roman(1, 15);
int betweenFiveAndTenInclusive = dummy.number().nextInt(5, 10);
boolean trueOrFalse = dummy.nextBoolean();
LocalDate birthdayBetween18And35 = dummy.dateAndTime().birthday(18, 35);
LocalDateTime upTo100YearsInThePast = dummy.dateAndTime().past(100, ChronoUnit.YEARS);
LocalDateTime upTo25YearsFrom1800 = dummy.dateAndTime().after(
LocalDateTime.parse("1800-01-01T00:00:00"), 25, ChronoUnit.YEARS);
MyEnum randomEnum = dummy.nextEnum(MyEnum.class);
String thisValueMightBeNull = dummy.chance(1, 3, () -> "hello");
String thisValueWillBeUnique = dummy.unique().value("fullNameGroup", () -> dummy.name().fullName());
List<String> fiveNames = dummy.listOf(5, () -> dummy.name().fullName());
Set<String> fourCities = dummy.setOf(4, () -> dummy.address().city());
String nameOrCity = dummy.oneOf(() -> dummy.name().fullName(), () -> dummy.address().city());
String elementFromArray = dummy.oneOf(new String[]{ "one", "two", "three" });
String elementFromVarArgs = dummy.oneOf("one", "two", "three");
String elementFromCollection = dummy.oneOf(Arrays.asList("one", "two", "three"));
dummy.unique().within(() -> dummy.name().fullName(), name -> {
// These names will only be unique within the context of this consumer
List<String> tenLocallyUniqueNames = dummy.listOf(10, name);
});
List<String> tenLocallyUniqueNames = dummy.unique().of(() -> dummy.name().fullName(),
name -> dummy.listOf(10, name));
// This resolves an expression, finding the appropriate values in yml files.
// Normally, this should be hidden away under a custom method
// (e.g. customDummy.maleAndFemaleNames()).
String resolvedExpression = dummy4j.expressionResolver()
.resolve("#{name.male_first_name}, #{name.female_first_name}");
// This finds and lists all methods containing the word "title":
String searchResult = dummy4j.find("title");
Please read the contributing guidelines if you are considering contributing to this project.
The goal of Dummy4j is to become the most versatile, extensible and easy to use dummy data generation library. To that end, all contributions are welcome - whether it's Pull Requests, architectural proposals or simply issues, feel free to share them as only a continued conversation around the use of this tool can lead to innovation.
While care will always be taken to keep Dummy4j backwards compatible, some breaking changes might prove beneficial enough to the project to include them in new releases. However, even in those cases the decision will not be taken lightly and all possible measures will be taken to ensure a smooth transition to a new version of the library.
Finally, if you disagree with any details of how this project is maintained, feel free to create an issue!