DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Related

  • Instancio: Random Test Data Generator for Java (Part 1)
  • Simplify Java Persistence Using Quarkus and Hibernate Reactive
  • Realistic Test Data Generation for Java Apps
  • Setting Up a CrateDB Cluster With Kubernetes to Store and Query Machine Data

Trending

  • Infrastructure as Code (IaC) Beyond the Basics
  • The Future of Java and AI: Coding in 2025
  • Memory Leak Due to Time-Taking finalize() Method
  • Integrating Model Context Protocol (MCP) With Microsoft Copilot Studio AI Agents
  1. DZone
  2. Coding
  3. Java
  4. Instancio: Test Data Generator for Java (Part 2)

Instancio: Test Data Generator for Java (Part 2)

Learn how to use the Instancio extension with JUnit 5. Instancio is a Java library that can create and auto-populate test objects.

By 
Arman Sharif user avatar
Arman Sharif
·
May. 21, 22 · Tutorial
Likes (3)
Comment
Save
Tweet
Share
7.0K Views

Join the DZone community and get the full member experience.

Join For Free

In part 1, we introduced Instancio and how it can be used to automate data setup in unit tests. To recap, Instancio is a library that automates data setup in unit tests, with the goal of reducing manual data setup. More specifically, it accepts a class (or a "type token") as an argument and returns a fully-populated instance of the class. Sticking to our Person class for all our examples, this can be done as follows:

Java
 
Person person = Instancio.create(Person.class);

Map<UUID, Person> person = Instancio.create(new TypeToken<Map<UUID, Person>>() {});


In this part, we are going to look at how to use Instancio with JUnit 5. We will discuss the Instancio extension class, injecting settings into test classes, running tests with custom seed values, and arguments source for @ParameterizedTests.

Instancio JUnit Extension

To get started, we will need to declare InstancioExtension on our test class. This is similar to using other test extensions, such as MockitoExtension. In fact, they can be combined if both are needed.

Java
 
@ExtendWith(InstancioExtension.class)
class ExampleTest {
    // ... snip
}


Since Instancio tests your code against randomly generated data, each time you execute your test, it is run against a new set of data. This brings up the question of how to reproduce the data if a test fails? One of the main things the extension provides is reporting the seed value that was used to generate the data. We can specify that seed value using the @Seed annotation, and Instancio will reproduce the data that caused the test to fail.

We will use the following example of converting a Person to PersonDTO.

Java
 
@ExtendWith(InstancioExtension.class)
class PersonToPersonDTOTest {

    @Test
    void verifyPersonDTO() {
        Person person = Instancio.create(Person.class);
      
        // Method under test
        PersonDTO dto = personMapper.toDto(person);
      
        assertThat(dto.getFirstName()).isEqualTo(person.getFirstName());
        assertThat(dto.getLastName()).isEqualTo(person.getSurname());
        // ... remaining assertions
    }
}


If this test fails, Instancio will report the failure as follows:

Test method 'verifyPersonDTO' failed with seed: 34567

Using the reported seed value, we can annotate the test method to reproduce the same data that caused the test to fail:

Java
 
@ExtendWith(InstancioExtension.class)
class ExampleTest{

    @Seed(34567)
    @Test
    void verifyPersonDTO() {
      // same code as before
    }
}


Placing the seed annotation as shown above will make the data effectively static. Each time the test is run, it will produce the same data,  allowing us to fix the cause of the failure. Once the cause is resolved, the @Seed annotation can be removed so that new data will be generated on each subsequent test run. How this works is described in more detail in the user guide, but to summarise, Instancio supplies each test method with a seed value. If the @Seed annotation is present, Instancio will use its value; if not, it will generate a random seed.

Injecting Settings Into Tests

Another feature provided by the extension is its support for injecting custom settings. Instancio settings are encapsulated by the Settings class. This allows overriding various parameters like generated number ranges; array, map, and collection sizes; whether generated values can be null, and so on. For example, by default, Instancio generates

  • non-null values
  • non-empty collections
  • positive numbers

Using @WithSettings annotation we can override default behaviour as follows:

Java
 
@ExtendWith(InstancioExtension.class)
class PersonToPersonDTOTest {

    @WithSettings
    private final Settings settings = Settings.create()
            .set(Keys.COLLECTION_MIN_SIZE, 0)
            .set(Keys.COLLECTION_MAX_SIZE, 5)
            .set(Keys.INTEGER_MIN, Integer.MIN_VALUE)
            .set(Keys.INTEGER_MIN, Integer.MAX_VALUE)
            .set(Keys.STRING_NULLABLE, true);

    @Test
    void verifyPersonDTO() {
        // person will populated using above settings
        Person person = Instancio.create(Person.class);
        // ... snip
    }
}


With the above settings in place, Instancio might generate null strings, empty collections, and negative integers. The settings will apply to test methods in this test class only (as a side note, settings can also be overridden globally by placing instancio.properties file at the root of the classpath).

Instancio Arguments Source

Last but not least, you can use the @InstancioSource annotation with @ParameterizedTest methods. JUnit 5 provides @ParameterizedTest support via the junit-jupiter-params dependency. Once you have that in place, you can declare a test method as follows:

Java
 
@ExtendWith(InstancioExtension.class)
class PersonToPersonDTOTest {

    @ParameterizedTest
    @InstancioSource(Person.class)
    void multipleArguments(Person person) {
        // provides a fully-populated person as an argument
    }
}


Instancio will provide a populated instance of the class specified in the annotation. You can specify any number of classes in the annotation. Just remember to declare a method argument for each class in the annotation:

Java
 
@ParameterizedTest
@InstancioSource(String.class, UUID.class, Foo.class)
void multipleArguments(String str, UUID uuid, Foo foo) {
    // any number of arguments can be specified...
}


There are a couple of important limitations to using @InstancioSource to be aware of.

First, it cannot provide instances of generic types. For example, there is no way to specify a List<Person>.

Second, you cannot customise the object as you would with the builder API. In other words, there is no way to specify something like this:

Java
 
Person person = Instancio.of(Person.class)
    .set(field(Phone.class, "countryCode"), "+1")
    .set(all(LocalDateTime.class), LocalDateTime.now())
    .create();

However, in situations where these limitations do not apply, it offers a convenient way of providing data to a test method. From simple values such as Strings and numbers to complex data types.

Try it Out

We've looked at a few features provided by Instancio. If you're curious to try it out, you can add the following dependency to your build by grabbing the latest version from Maven Central:

 https://search.maven.org/artifact/org.instancio/instancio-junit

Maven

XML
 
<dependency>
    <groupId>org.instancio</groupId>
    <artifactId>instancio-junit</artifactId>
    <version>${instancio.version}</version>
    <scope>test</scope>
</dependency>

Gradle

Groovy
 
dependencies {
    testImplementation 'org.instancio:instancio-junit:$instancioVersion'
}

For more information, check out

  • https://www.instancio.org - reference documentation
  • https://www.github.com/instancio/instancio - sources
Test data Java (programming language)

Opinions expressed by DZone contributors are their own.

Related

  • Instancio: Random Test Data Generator for Java (Part 1)
  • Simplify Java Persistence Using Quarkus and Hibernate Reactive
  • Realistic Test Data Generation for Java Apps
  • Setting Up a CrateDB Cluster With Kubernetes to Store and Query Machine Data

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!