Testcontainers Initscript
June 22, 2020
This is the second part of a series of three posts about Testcontainers. In the first part
the Testcontainers library was introduced. In this post we’ll explore a way to create test data for your
tests using init scripts. We’re going expand upon the code introduced on the first part so you might want
to do that, if you already know about Testcontainers you can accompany this post by cloning the repo here
and checking out the simple-test
tag.
The Problem
Let’s say that before your tests run you want to create some state before that. Perhaps you would like to have some tables populated so that you don’t have to create all that state on code. You can do that on the container setup by specifying a sql file like this:
companion object {
@Container
val container = KPostgresContainer()
.withInitScript("add_users.sql")
.withExposedPorts(5432)
.withDatabaseName("test")
.withUsername("postgres")
.withPassword("postgres")
}
The withInitScript
expects a file name and will search within your resources
folder. We’re going to create
the database using a sql script instead of relying on spring.jpa.hibernate.ddl-auto=create
, so delete this line
from application.properties
. this is necessary for two reasons. First the create
option drops existing data and creates it again. Second this creating is done only when Spring is started and
withInitScript
runs before that so if we tried only to add the data, there would be no table created.
Create the add_users.sql
on the test/src/resources
folder containing:
CREATE TABLE users(
id INT,
first_name VARCHAR,
last_name VARCHAR
);
INSERT INTO users (id, first_name, last_name) VALUES (2, 'Addrianne', 'Lenker'), (3, 'Phoebe', 'Bridges');
The script is pretty straightforward, it just creates the database table and inserts two users on it. Now, let’s create a test to validate this new setup is working:
Add the following test to UserRepositoryTest.kt
:
@Test
fun `test user are present`() {
assertEquals("Addrianne", userRepository.findById(2).get().firstName)
assertEquals("Phoebe", userRepository.findById(3).get().firstName)
}
Run the test and it should pass, confirming that the script was run before the test starts. You can see the
code for this post here. Just clone and checkout the tag initscript: git checkout initscript
.
In the last post we’ll look at a more interesting pattern, to use a Docker image with data already prepopulated so that we don’t have to run init scripts every time our tests are started.