Skip to main content

Microservice - Unit Test - Repository Layer

Now that we have completed the first round of development of our lead microservice, it is time to focus on some testing. I will follow a bottom-up approach and start by writing unit tests for the repository layer.

In order to write unit tests, I will make use of the Spring Test Framework and Spring Boot Test support. Spring Boot makes it extremely easy to unit test slices of the application. We can use @DataJpaTest and just unit test the database layer with an embedded database like H2. However, there are some gotchas (I do not know exactly what at this moment), the @DataJpaTest does not work if you have extended the Spring Data JPA to add a custom method for all the repositories. The problem I found was that the when running the Spring Boot application, everything works fine and the custom method works fine and the query returns the correct results. However, when the unit test is run, Spring Data JPA fails, complaining that it is not able to find an attribute for the entity/type.

So to write unit tests for the repository of the lead microservice, I will use the standard @SpringBootTest annotation. The goal here is to unit test and hence only beans relevant to the repository layer are created. To achieve this we will have to prevent unnecessary beans from being created - for example, the controller beans etc. Remember unit tests have to be cheap and must run fast. This will ensure quick feedback and promote continuous delivery principles. Note that the repository unit tests are created and run in an embedded database and hence they are very fast.

Listing 1 - below shows the initial version of the repository unit test class.
There are few important items to note in Listing 1.

  • Most of the methods are not yet implemented. They will be implemented along with future posts. 
  • @Transactional - annotation ensures that the transaction which started at the beginning of the test method is rolled back after the method completes. In other words, the test data that is created is removed. 
  • @SpringBootTest(webEnvironment=WebEnvironment.NONE) - ensures that web environment is not started in other words no controllers or web layer beans are created ensuring that the test runs fast. 
  • @DatabaseSetup("lead.xml") - this is an interesting annotation. I have integrated the spring-test-dbunit project to integrate DBUnit utilities with Spring Boot Test. The detailed documentation of this project can be found at this link - https://springtestdbunit.github.io/spring-test-dbunit/
Few words on Spring test db unit
  • This project makes it extremely easy to create test data and then clean it up.
  • @DatabaseSetup - can be added both at the class and method level. The transaction starts with the DB setup process and it inserts the data in the lead.xml in this example into the database for easy test data setup. Once the test completes and transaction rolls back, this data is removed. When the annotation is added at the class level, then it is run for all the test methods. It can also be added to individual test methods and in that case, the test data will be loaded only for that particular method. 
  • In order to load the lead.xml file for test data it must be stored under the same package name as the repository class. However, the source folder will be - 'src/test/resources'
  • The DbUnitTestExecutionListener will also be required to include Spring-test-db-unit. as shown in the snippet below.


Figure 1 - Test code and resource folder
Figure 2 - JUnit All Green
Finally, some changes are required in the build.gradle dependency management section to include the spring-test-dbunit jars in the lead microservice project. This is shown in snippet below.


Comments

Popular posts from this blog

Breaking down the CRM monolith

In my previous posts, I have shared some theory regarding microservices. But it's time to start some implementation. I love to write code and see and feel things working. So I will start a series to refactor a monolithic CRM system and transform it into microservices based flexible software. Big ball of mud. Customer Relationship Management(CRM) is that giant software which existed since time immemorial and is used by all companies in some form or shape. Big enterprises will buy CRM software (also known as packages) from top CRM vendors like Oracle, SAP, Salesforce etc and then employ an army of consultants to try and implement it. Most of the classic CRM systems in the market today, even if deployed on the cloud are the big monolithic ball of mud. They are the gigantic piece of software with the huge feature set. Most often those requirements are surplus to the requirement or they will not fit into the processes of the company. So the company has to hire these certified consu...

Part 3 - Integrating Tiles, Thymeleaf and Spring MVC 3

In this post I will demonstrate how to integrate Apache Tiles with Thymeleaf. This is very simple. The first step is to include the tiles and thymeleaf-tiles extension dependencies. I will include them in the pom.xml. Note we wil lbe using Tiles 2.2.2 Listing 1 - parent/pom.xml --- thymeleaf-tiles and tiles dependencies <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> <!-- Tiles --> <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> <dependency> <groupId>org.apache.tiles</groupId> <artifactId>tiles-core</artifactId> <version>${tiles.version}</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.apache.tiles</groupId> <artifactId>tiles-template</artifactId> <version>${tiles.version}</version> <scope>compile</s...

CKEDITOR 3.x - Simplest Ajax Submit Plugin

  I have assumed that you have downloaded and got started with CKEDITOR. Step 1 – The html file is shown below: <html> <head> <title>Writer</title> <meta content="text/html; charset=utf-8" http-equiv="content-type" /> <script type="text/javascript" src="ckeditor/ckeditor.js"></script> <script type="text/javascript" src="js/jquery-1.4.2.min.js"></script> <style> .cke_contents { height: 400px !important; } </style> </head> <body> <form action="sample_posteddata.php" method="post"> <textarea id="editor" > </textarea> <script type="text/javascript"> //<![CDATA[ CKEDITOR.replace( 'editor', { fullPage : true, uiColor : '#9AB8F3', toolbar : 'MyToolbar' }); //]]> </script> </form> </body> </html> Note that the jquery js...