I want to create test data for my tests with underlying in-memory database. Common approach is to create some test_data.sql file and create test objects with inserts. And then reference these objects in java test.
I read in Growing Object-Oriented Software, Guided by Tests, that tests don't need to go deep in details. For example, if test wants existing User with NEW status, then he don't need to create user and fill all it's fields. But he should only tell, that he wants user with NEW status and all other fields should be filled with default values.
So I want helper methods, like this one:
User user = user(UserStatus.NEW); // inserts user in database
// ... use persistent user instance in test
But my database schema has much tables and I came to following code:
Domain domain = new DomainBuilder().user(UserStatus.NEW).agreement().account().account().build();
Doman class:
public class Domain {
private User user;
private Agreement agreement;
private Account account;
// getters/setters
}
This code creates user, agreement(with FK to user), two accounts(with FK to agreement) and returns Domain object, which contains these entities.
So with this code I basically can setup test data for particular test in one line.
This test data generation approach has following advantages over SQL:
I don't stick to all table columns, if some column/constraint is added/removed , then I don't need to change test data generation in my test.
It's more concise way, that SQL: I can setup test data in one line whereas SQL approach requires writing INSERT for each object.
It's less time consuming. Yes, first you start using this approach you have to spend some time for implementing such domain builder, but once you are done, then you save much time.
Centralized objects creation. If your database schema changed, then you have to change object creation logic only in one place.
You don't need to stick with java constants like USER_WITH_NEW_STATUS_ID.
My question is:
Does anybody also come to this approach and what libraries/tools/conventions you use for this ?
UPDATE: I use such approach in few test types:
repositories tests (e.g. repository filters objects correctly, or it returns objects list in correct order).
business logic + database integration test(unit tests are good, but sometimes I need to be 100% sure my business logic and repository logic are consistent