DEV Community

Cover image for Instancio: Data Generator For Unit Tests
armandino
armandino

Posted on • Edited on

4 3

Instancio: Data Generator For Unit Tests

This post is about reducing manual data setup in unit tests. Typically such setup involves instantiating some classes and calling a bunch of setters. For example, in the the following test this is done in the createBookDTO() method:

Note: links to source code provided at the end.

// Class under test
private final BookMapper bookMapper = new BookMapper();

@Test
void map() {
    // Given
    BookDTO bookDto = createBookDTO();

    // When
    Book book = bookMapper.toEntity(bookDto);

    // Then
assertThat(book.getTitle()).isEqualTo(bookDto.getBookTitle());
    // ... snip ... remaining assertions
}

// Data setup
private BookDTO createBookDTO() {
     AuthorDTO authorDto = new AuthorDTO();
     authorDto.setAuthorId(UUID.randomUUID().toString());
     authorDto.setFirstName("Jane");
     authorDto.setLastName("Doe");

     BookDTO bookDto = new BookDTO();
     bookDto.setBookId(UUID.randomUUID().toString());
     bookDto.setIsbn("test-isbn");
     bookDto.setBookTitle("test-title");
     bookDto.setAuthor(authorDto);
     bookDto.setGenre(Genre.FICTION);
     bookDto.setPublishedOn(LocalDate.of(1865, 3, 17));
     bookDto.setNumberOfPages(123);
     bookDto.setPriceCents(3099);
     return bookDto;
}
Enter fullscreen mode Exit fullscreen mode

The setup done in createBookDTO() is very typical for unit tests. However, it can be quite tedious, especially when dealing with large classes. What's more is that often the values themselves don't actually matter. Whether you set the name to "Jane Doe" or "Foo Bar" makes no difference. The end result is the same.

If values don't matter, then why not use a library to create and populate an object with random data? This is exactly what Instancio does. It is a library that generates objects for unit tests. Using Instancio, we can create a BookDTO instance as follows:

private BookDTO createBookDTO() {
    return Instancio.create(BookDTO.class);
}
Enter fullscreen mode Exit fullscreen mode

This seems like a step in the right direction, but what if we need to customise some values of BookDTO? Let's say the BookMapper class that we are testing converts string UUID values to UUID type:

UUID.fromString(bookId) // need a valid UUID string!
Enter fullscreen mode Exit fullscreen mode

In this case, the test will fail unless our test objects contain valid ids (notice that setAuthorId() and setBookId() in the original createBookDTO() method are both set to UUID.randomUUID().toString()). To achieve this, we can use Instancio's builder API to set custom values:

Instancio.of(BookDTO.class)
    .set(field(BookDTO.class, "bookId"), UUID.randomUUID().toString())
    .set(field(AuthorDTO.class, "authorId"), UUID.randomUUID().toString())
    .create();
Enter fullscreen mode Exit fullscreen mode

For this simple test the above change is sufficient and now our test will pass. However, Instancio supports a number of other features for customising generated objects, for example:

Instancio.of(BookDTO.class)
    .generate(field("genre"), gen -> gen.oneOf(Genre.CRIME, Genre.SCIFI, Genre.FANTASY))
    .generate(field("isbn"), gen -> gen.text().pattern("#d-#d#d#d#d#d-#d#d#d-#d"))
    .generate(field("numberOfPages"), gen -> gen.ints().range(100, 999))
    .create();
Enter fullscreen mode Exit fullscreen mode

There might be a follow up article to go into more detail. Please leave a comment if you'd like to see more examples, or if you have any questions. All feedback is welcome!

If you are interested in learning more, please see the user guide which also has a number of examples.

You can find the book-mapper-sample project at https://github.com/instancio/instancio-samples

Links

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (1)

Collapse
 
eawanmacen profile image
eawanmacen
Comment hidden by post author

Some comments have been hidden by the post's author - find out more

Heroku

This site is built on Heroku

Join the ranks of developers at Salesforce, Airbase, DEV, and more who deploy their mission critical applications on Heroku. Sign up today and launch your first app!

Get Started

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay