Using the Same DbUnit Data Sets From Multiple Maven Modules

After we have finished this lesson, we:

  • Understand why it’s a good idea to use the same DbUnit data sets from multiple Maven modules.
  • Know how we can publish our DbUnit data sets to a Maven repository.
  • Can use the published DbUnit data sets from another Maven module.
  • Understand how we can make our life easier when we are working with DbUnit data sets which are used by multiple Maven modules.

Get the source code from Github

Why Should We Care?

If we are working with a Maven project that has multiple modules, it’s possible that these modules access the same database tables. If we are in this situation, we should use the same DbUnit data sets when we write integration tests for these modules because this approach makes our integration tests easier to write and maintain.

To be more specific, this approach has the following benefits:

  • We don’t have to create our test data from the scratch when we write integration tests for a new Maven module. We can simply use the DbUnit data sets which contain the shared test data.
  • If we make changes to our data model, we have to change only one Maven project.
  • If we want to change the shared test data, we have to change only one Maven project.

To summarize, it’s a good idea to use shared DbUnit data sets because making changes to only one place is a lot faster (and less risky) than making the same changes to multiple Maven modules.

Next, we will find out how we can publish our DbUnit data sets to a Maven repository.

Publishing Our DbUnit Data Sets to a Maven Repository

When we want to use the same DbUnit data sets from multiple Maven modules, the first thing that we have to do is to publish our DbUnit data sets to a Maven repository. We can publish our DbUnit data sets by following these steps:

First, we have to create a new Maven project which contains our DbUnit data sets. After we have created our Maven project, our pom.xml file looks as follows:

 1<project xmlns="http://maven.apache.org/POM/4.0.0"
 2         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 4    <modelVersion>4.0.0</modelVersion>
 5    <groupId>com.testwithspring.master</groupId>
 6    <artifactId>test-data-sets</artifactId>
 7    <version>0.1</version>
 8    <name>Test Data Sets</name>
 9    <description>
10        This example demonstrates how you can package DbUnit data sets
11	    into a jar file.
12    </description>
13</project>

Second, we have to put our DbUnit data set files to the src/main/resources directory. This ensures that our DbUnit data sets are packaged into the created jar file. The following figure identifies the DbUnit data sets which are found from the src/main/resources directory of our example application:

Third, we have to package our DbUnit data sets into a jar file and publish that jar file to a Maven repository. Because this is an example, we will publish our jar file to our local Maven repository. We can do this by running the command: mvn clean install at command prompt.

If you are working with a real-life software project, you should publish the jar file to a private Maven repository that can be accessed only from a private network. The benefit of this approach is that you don’t have to publish the jar file to your local Maven repository every time when someone makes changes to the test data. Instead, you can simply update the version number of the correct dependency.

Let’s move on and find out how we can use our DbUnit data sets from another Maven module.

Using Our DbUnit Data Sets From Another Maven Module

When we want to use our DbUnit data sets from another Maven module, we have to follow these steps:

First, we have to ensure that our DbUnit data sets are found from the classpath. We can do this by declaring the following dependency in our POM file:

1<dependency>
2    <groupId>com.testwithspring.master</groupId>
3    <artifactId>test-data-sets</artifactId>
4    <version>0.1</version>
5    <scope>test</scope>
6</dependency>

Second, because the shared DbUnit data sets are found from the classpath, we can use them in the same way as “local” DbUnit data sets.

For example, let’s configure the test data which is used by an integration test which ensures that the TaskRepository object is working as expected when it creates a new task. After we have configured the test data, the source code of our test class looks as follows:

 1import com.github.springtestdbunit.annotation.DatabaseSetup
 2import com.github.springtestdbunit.annotation.DbUnitConfiguration
 3import com.github.springtestdbunit.dataset.ReplacementDataSetLoader
 4import com.testwithspring.master.DatabaseIntegrationTest
 5import org.assertj.core.api.junit.jupiter.SoftAssertionsExtension
 6import org.junit.jupiter.api.DisplayName
 7import org.junit.jupiter.api.extension.ExtendWith
 8import org.springframework.beans.factory.annotation.Autowired
 9import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
10
11@DatabaseIntegrationTest
12@ExtendWith(SoftAssertionsExtension::class)
13@DatabaseSetup(value = [
14    "/com/testwithspring/master/users.xml",
15    "/com/testwithspring/master/no-tasks-and-tags.xml"
16])
17@DbUnitConfiguration(dataSetLoader = ReplacementDataSetLoader::class)
18@DisplayName("Create a new task")
19private class CreateNewTaskTest(
20        @Autowired private val jdbcTemplate: NamedParameterJdbcTemplate,
21        @Autowired private val repository: TaskRepository
22) {
23
24}

Next, we will take a look at some best practices which make our life easier when we are working with DbUnit data sets which are used from multiple Maven modules.

Best Practices

We can make our life a lot easier by following these rules:

  • If we make any changes to the Maven project which contains our DbUnit data sets, we must increase its version number. This ensures that our changes cannot break the Maven modules which use our DbUnit data sets.
  • If we use constant classes which contain the test data found from the database, we should put these classes to the Maven project which contains our DbUnit data sets. Also, we should put these classes to the src/main/java directory because this ensures that these classes are packaged into the created jar file. This approach makes our test data easier to maintain. For example, if we have to make changes to our test data, we have to change only one Maven project.
  • We must update our DbUnit data sets every time when we make changes to our data model. This ensures that the changes made to our data model cannot break our integration tests.
  • The version number of our data model must be included in the version number of the dependency which provides the test data for our integration tests. This saves time because we don’t have to wonder which data set version is compatible with our data model.
  • The DbUnit data sets, which are used by multiple Maven modules, must not contain module specific test data because adding module specific test data to these data sets will make them hard to read and maintain. If we want to use module specific test data, we must put the DbUnit data sets to the module which uses them.

We can now publish DbUnit data sets to a Maven repository and use these data sets from another Maven module. Let’s summarize what we learned from this lesson.

Summary

This lesson has taught us five things:

  • It’s a good idea to use shared DbUnit data sets because making changes to only one place is a lot faster (and less risky) than making the same changes to multiple Maven modules.
  • If we want to use shared DbUnit data sets, we must publish these data sets to a Maven repository.
  • Because the shared DbUnit data sets are found from the classpath, we can use them in the same way as “local” DbUnit data sets.
  • The version number of our data model must be included in the version number of the dependency which provides the test data for our integration tests.
  • We shouldn’t add module specific test data to the DbUnit data sets which are used by multiple Maven modules.

Get the source code from Github