autofilldb
is a lightweight library that can automatically populate mock data in database, while satisfying column constraints. It can be used to simplify setting up test data while writing database integration tests in Java projects.
Suppose you have an employee
table that has an id
column as the primary key and various other columns, some of which may have a not null
constraint. You want to insert a new row in this table but you only care about the id
field in your particular context. Normally you'd need to insert a value in all the mandatory columns. But with autofilldb
, your data setup could be as simple as:
autoFill.into("employee", ImmutableMap.of("id", 1))
All other column values that are irrelevant to the use case, but are necessary for satisfying integrity constraints of the table, are auto generated by the library.
This library can produce valid mock data to satisfy not null
and foreign key
constraints. All generated values comply with column constraints like length of column, uniqueness and data type etc.
autofilldb
requires an instance type javax.sql.DataSource
to connect to the database.
Let's say there are following three tables in your project:
Organisation
column | type | key/constraint |
---|---|---|
id | integer | primary key |
name | varchar | - |
Department
column | type | key/constraint |
---|---|---|
id | integer | primary key |
name | varchar | |
organisation_id | integer | foreign key references organisation(id) |
Employee
column | type | key/constraint |
---|---|---|
id | integer | primary key |
name | varchar | not null |
phone_number | varchar | not null, unique |
varchar | not null, unique | |
department_id | integer | foreign key references department(id) |
Suppose you want to test a simple function findEmployeeByEmail
. For this, you'd need to insert a few rows in the Employee table. Even though just populating email and id fields in the Employee table would suffice to test this functionality, you'd need to populate all the not null
columns of the Employee table. Furthermore, there is a foreign key dependency from Employee to Department and Department to Organisation. So you'd need to insert a row each in Department and Organisation tables even though they have nothing to do with the use case you are trying to test.
The data setup for a database integration test would look something like this:
jdbcTemplate.execute("insert into organisation(id) values(10)");
jdbcTemplate.execute("insert into department(id, organisation_id) values(200, 10)");
jdbcTemplate.execute("insert into employee(id, name, phone_number, email, department_id) values(3001, 'John', '(480) 671-9585', 'john@example.com', 200)");
jdbcTemplate.execute("insert into employee(id, name, phone_number, email, department_id) values(3002, 'Jane', '(130) 516-6392', 'jane@example.com', 200)");
There could be many more columns with not null
constraint, and you'd need to populate them all in your simple test case.
But with autofilldb
, you can keep the data setup focused on only those column values that are required in the unit test. The above setup can be rewritten as following:
AutoFill autoFill = new AutoFill(dataSource);
autoFill.into("employee", ImmutableMap.of("id", 3001, "email", "john@example.com"));
autoFill.into("employee", ImmutableMap.of("id", 3002, "email", "jane@example.com"));
You'd need to instantiate an AutoFill
object in your test class. The AutoFill.into
method takes in the table name and a Map of column name and value pairs that are relevant to the unit test.
The project has two modules:
autofilldb
is the actual libraryautofilldb-tester
tests the library against a MySQL instance running in a Docker container.
Command to build the project: ./gradlew clean build -x signArchives