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

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

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

How to Stand up a Spring Cloud Config Server?

Setup and Configure Spring Cloud Config Server Project Spring Cloud Config Server is just another Spring Boot application. It provides several infrastructure micro services to centralize access to configuration information backed by a version controlled (well at least in the case of default GIT storage) repository. Step 1 - Create a Spring Boot project in STS with the dependencies shown in Figure 2. Figure 1 - Creating Spring Boot project to setup Spring Cloud Config Server Figure 2 - Spring Cloud Config Server dependencies Click on 'Finish' to complete the creation of the Spring Boot project in STS. The build.gradle file is shown in listing below. There is only one dependency to the Spring Cloud Config Server. Also Spring Cloud release train 'Dalston.SR1'. Step 2 - Annotate the class containing main method The next step is to annotate the ConfigServerInfraApplication class with  @EnableConfigServer That's all is needed on the Java si