In episode 22 we how to seed a database with spring's @Sql annotation so lets extend it and find out how to test a domain with database interactions.
Detailed Video Notes
For our exercise we have been given a user story to "Update an existing person's password" which will require us to create a Person table, POJO and a data access object. We will use spring's jdbcTemplate to interact with the database but it could be substituted by injecting mybatis or hibernate data access beans. Once those pieces are created we will put it together an integration test.
This process may vary depending what techniques and methodologies you are using such as TDD.
Project set up
Let's get started by creating a spring boot project from the starter web site selecting
spring-boot-starter-web. We will then download and import the maven project into eclipse while adding derby as additional dependency in the pom.xml. Spring-boot recognizes derby is on the classpath and auto configures an embedded database which means you do not need to specify any connection URLs or driver class names (pretty neat). If you are wanting to dig into the specifics check out EmbeddedDatabaseConnection and EmbeddedDataSourceConfiguration.
Creating Person domain and DAO
Next lets create a
Person POJO and
PersonDAO. As we mentioned earlier the
PersonDAO will use
JdbcTemplate abstraction to access the database. We implemented a
PersonRowMapper that implements
RowMapper to map result set row to a Person object, a
Setting up the database
Once the foundation is created, we will want to write a test to validate that a person's password was updated. An important thing to mention is when running integration tests against a database is that is in a known state before each test to have consistent reproducible tests. To achieve this we will use spring's @Sql and @SqlGroup annotation.
We covered this in detail in episode 22 so at a high level using these annotations we create a person table, preload the entry of "Fred" and drop the table upon completion of the test all against our embedded database.
Writing the test
After the database and data is set up we are ready to write our unit test. Since we know we seeded the database with a person and their id equaling one, we will create a
Person object setting the id to 1 and the password to "wilma". In the event that we didn't know which person existed we could first queried the database to get a random person and followed the same steps.
Next calling the
personDAO.updatePassword and passing the
Person object we just created will execute an update statement which we can see by examining the logs.
Finally we can validate the update occured by calling
Putting it all together
Testing interactions between a domain and a database can be challenging and spring has made it easy to set up, tear down and execute scripts against a database. It is important to find the balance between what an integration test can offer and interactions you can test with mocking frameworks such as mockito.
Thanks for joining in today's level up, have a great day!