Skip to main content

Java Test Data Generator: Datafaker and Instancio for JUnit 5 Test Fixtures

Datafaker 2.7.0 is the maintained fork of `DiUS/java-faker`, and listicles still teach the predecessor under its old name. This guide shows how to pair Datafaker with Instancio's JUnit 5 extension so the framework generates the object graph and Datafaker fills the human-readable leaves with realistic names and addresses.

Libraries confirmed

Datafaker `net.datafaker:datafaker:2.7.0` and Instancio `org.instancio:instancio-junit:6.0.0-RC4` with JUnit 5. The DiUS/java-faker predecessor is abandoned; replace `com.github.javafaker:javafaker` with the Datafaker coordinate (Datafaker README, retrieved 2026-08-01).

Maven/Gradle coordinates, InstancioExtension seed-on-failure, and @Seed replay

Instancio owns object topology; Datafaker owns vocabulary (names, addresses). With @ExtendWith(InstancioExtension.class), a failing test prints the seed that drove the run. Copy that number into @Seed(n) on the test method to replay the exact failure, then remove the annotation after the fix (Instancio user guide "Reproducing failed tests," retrieved 2026-08-01).

Runnable code sample

Verified against library docs retrieved 2026-08-01. The second method shows the @Seed replay loop; replace 12345L with the seed printed by InstancioExtension in CI.

// Maven/Gradle coordinates (retrieved 2026-08-01):
//   testImplementation("net.datafaker:datafaker:2.7.0")
//   testImplementation("org.instancio:instancio-junit:6.0.0-RC4")
// DiUS/java-faker is abandoned; use Datafaker (net.datafaker:datafaker).

import static org.instancio.Select.field;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.util.List;
import net.datafaker.Faker;
import org.instancio.Instancio;
import org.instancio.junit.InstancioExtension;
import org.instancio.junit.Seed;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;

@ExtendWith(InstancioExtension.class)
class ShipmentFixtureTest {

    record Shipment(String consignee, String street, String contactSurname, int parcels) {}

    private static final Faker FAKER = new Faker();

    @Test
    void shipmentsCarryRealisticAddressesAndBoundedParcelCounts() {
        List<Shipment> shipments = Instancio.ofList(Shipment.class)
                .size(25)
                .supply(field(Shipment::consignee), () -> FAKER.name().fullName())
                .supply(field(Shipment::street), () -> FAKER.address().streetAddress())
                .supply(field(Shipment::contactSurname), () -> FAKER.name().lastName())
                .generate(field(Shipment::parcels), gen -> gen.ints().range(1, 12))
                .create();

        assertTrue(shipments.stream().allMatch(s -> s.parcels() >= 1 && s.parcels() <= 12));
    }

    // InstancioExtension prints the seed on failure. Paste that number here to replay CI.
    @Test
    @Seed(12345L)
    void reproduceAFailingCiRunWithThePrintedSeed() {
        List<Shipment> shipments = Instancio.ofList(Shipment.class)
                .size(25)
                .supply(field(Shipment::consignee), () -> FAKER.name().fullName())
                .supply(field(Shipment::street), () -> FAKER.address().streetAddress())
                .supply(field(Shipment::contactSurname), () -> FAKER.name().lastName())
                .generate(field(Shipment::parcels), gen -> gen.ints().range(1, 12))
                .create();

        assertTrue(shipments.stream().allMatch(s -> s.parcels() >= 1 && s.parcels() <= 12));
    }
}

When to use Generate-Data instead

Use in-process libraries when fixtures must live next to JUnit assertions in CI. Use the free generator when you need a downloadable file (csv, json, xml, parquet, xlsx, jsonl, hf-datasets when signed in), labeled duplicates with Master ID / Duplicate Type, or exports beyond what your library emits. Anonymous use is capped at 100 rows, 6 fields, 3 exports, and CSV only. See the generator comparison and export formats guide.

Frequently asked questions

Is `javafaker` the same thing as Datafaker, and which one should I depend on?

Datafaker is the fork, and it is the one under active release. The README at https://github.com/datafaker-net/datafaker states: "This library is a modern fork of java-faker with up to date libraries and several newly added Fake Generators." Datafaker 2.7.0 was released on 2026-06-24. If your `pom.xml` or `build.gradle` references `com.github.javafaker:javafaker`, you are on the predecessor coordinate; replace the group ID with `net.datafaker:datafaker`. Confirmed on 2026-08-01 from the Datafaker GitHub repo.

Do I need both Datafaker and Instancio, or does one cover it?

They do different jobs. The Instancio user guide frames its own role as walking an object graph and filling fields with arbitrary valid values ("this is not its goal ... most unit tests do not care what the actual values are"). Datafaker fills the human-readable leaf values (names, addresses, emails) that Instancio would otherwise generate as random strings. The division: Instancio owns the object topology; Datafaker owns the vocabulary. The Vicky Ivanova Medium post (https://vicky-ivanova.medium.com/beyond-the-happy-path-synthetic-test-data-in-java-with-datafaker-and-instancio-76096ea05bfe, observed 2026-08-01) shows the combining recipe in context.

My randomised test failed once in CI. How do I reproduce it?

With `@ExtendWith(InstancioExtension.class)`, the extension prints the seed that drove the failing run to the test output automatically. Copy the printed seed number and add `@Seed(that_number)` to the test method. The same run will reproduce exactly. Remove the annotation once you have found and fixed the bug. This is documented in the Instancio user guide at https://www.instancio.org/user-guide/ under "Reproducing failed tests." Observed 2026-08-01.

More Java testing guides