1

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

Oleksandr.Bezhan
  • 2,028
  • 3
  • 22
  • 31
  • what are you going to test? your schema? your Pojos? your data access layer? – Marco Forberg Apr 18 '13 at 07:15
  • 2
    I haven't seen this approach before. But it actually looks quite nice. However you should be careful that you create valid objects and object graphs. Otherwise your tests may lead to false statements about the correctness of your application. But what I wonder is why you still need the database in such cases. This may be a sign of tight coupling of business logic and database. Business logic tests should be able to run without the DB and data access tests shouldn't use any business logic. A plus is that you have compile time checking when creating your instances and refactoring support. – SpaceTrucker Apr 18 '13 at 07:28
  • Yes, builder may produce wrong object graph, but you can write test for it(it will be pretty simple) and be sure it works fine. – Oleksandr.Bezhan Apr 18 '13 at 07:33

1 Answers1

0

Have you checked DBUnit?

http://www.dbunit.org/

It is an extension of JUnit targeted for database-driven projects that, among other things, puts your database into a known state between test runs.

The data set is a simple XML file.

  • Thanks for suggestion, but it's not what I'm looking for. The idea is to create objects graph using centralized methods and don't dig deeply in object attributes. – Oleksandr.Bezhan Apr 18 '13 at 11:54