1. Overview
In this article, I will discuss on how to write unit tests in spring boot. Assumption here is that we are using dependency injection in our code. In order to test the methods of classes that uses dependency injection we need to inject this dependencies in unit tests. We will not use any mocking framework such as Mockito.
2. Understanding SpringJUnit4ClassRunner
SpringJUnit4ClassRunner is used to implement junit unit and integration test and simultaneously reap the benefits for TestContext framework. The TestContext framework provides support for application contexts, dependency injection of test instances and several other important functionalities. We can use SpringJUnit4ClassRunner by annotating the test class as below:
@RunWith(SpringJUnit4ClassRunner.class) public class TransactionTest { }
3. Understanding @ContextConfiguration
@ContextConfiguration annotation defines a class level metadata that is used to determine how to load and configure the ApplicationContext. @ContextConfiguration declares the application context resource locations or annotated classes used to load the context.
Our configuration will go in TestConfiguration class.
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = { TestConfiguration.class }) public class TransactionTest { }
4. Defining class TestConfiguration.
@Configuration @ComponentScan(basePackages = "com.justamonad") public class TestConfiguration { }
5. Adding beans in TestConfiguration.
If the injection is used for objects that are not in component scan package then we need to define beans in TestConfiguration class. Let’s say that we used injection to get instance of ObjectMapper class like below.
@Inject private ObjectMapper objectMapper;
TestConfiguration class won’t be able to inject ObjectMapper as the package that it comes from package com.fasterxml.jackson.databind. So we now need to insert a Bean for ObjectMapper in order for our tests to use it.
@Configuration @ComponentScan(basePackages = "com.justamonad") public class TestConfiguration { @Bean public ObjectMapper objectMapper() { return new ObjectMapper(); } }
6. Start writing tests.
We are done with all the setup. Now we can start writing tests. Just inject the classes that are eligible for component scan i.e. annotated with @Named, @Component and others.
import org.junit.Assert; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = { TestConfiguration.class }) public class TransactionTest { @Inject private TransactionRequestValidator transactionReqValidator; @Test public void testNullTransaction() { try { Transaction txn = null; transactionReqValidator.validate(txn); // If below line is executed means validator // didn't throw an exception. // It must throw an exception Assert.fail(); } catch (RequestValidationException ex) { // If exception is thrown means validator // threw exception which is // expected output. Assert.assertTrue(true); } } }
7. Conclusion
In this article, we saw how to write unit tests in spring boot using dependency injection.