Spring boot with Mockito and Kotlin

Posted by Java developer blog on November 4, 2019

Overview

It’s a good practice to write a unit test to verify your code because it’s a basement of the Testing Pyramid. A unit test usually checks a single method. In most cases, it is hard to write a unit test without mocking external dependencies such as database, external web server, etc.

In this post, we will explore how to how to write a mock unit test with Spring boot and Kotlin.

Mockito library

There is a library that helps you to create a mock. The library is Mockito. I recommend to use a thin Kotlin wrapper) around the library.

Firstly, you need to add dependencies to a pom file:

1
2
3
4
5
6
7
8
<!-- https://mvnrepository.com/artifact/com.nhaarman/mockito-kotlin -->
<dependency>
    <groupId>com.nhaarman</groupId>
    <artifactId>mockito-kotlin</artifactId>
    <version>1.6.0</version>
    <scope>test</scope>
</dependency>

Inject a mock with the help of @Mock and @InjectMocks

Then, we will be able to mock a bean and inject it with the help of @Mock and @InjectMocks annotations correspondingly:

1
2
3
4
5
6
7
8
9
10
11
12
13
@RunWith(MockitoJUnitRunner::class)
class ExampleMockTest {
	@Mock
	lateinit var dependancy: Dependency

	@InjectMocks
	lateinit var service: Service

	@Test
	fun foo() {
		...
	}	
}

@RunWith(MockitoJUnitRunner::class) - it is used to tell the JUnit an entry point

Inject a mock directly through a constructor

You could also inject a mock directly through a constructor of a bean. In some cases it could be helpful. For example, if a constructor parameter as String type.

Let’s see an example:

1
2
3
4
5
6
7
8
9
10
11
12
@RunWith(MockitoJUnitRunner::class)
class ExampleMockTest {
	@Mock
	lateinit var dependancy: Dependency

	lateinit var service: Service

	@Test
	fun foo() {
		service = Service(dependancy)
	}	
}

Inject a mock bean into an Application context

Sometimes we need to inject a mock bean into an Application context. We have to use @MockBean and @Autowired instead of @Mock and @InjectMocks annotations correspondingly. Also, don’t forget to put all required Spring annotations on a test class instead of @RunWith(MockitoJUnitRunner::class).

There is an example below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@ActiveProfiles("test")
@RunWith(SpringRunner::class)
@SpringBootTest
@TestPropertySource(locations = ["classpath:application-test.properties"])
class ExampleSpringMockTest {
	@MockBean
	lateinit var dependancy: Dependency

	@Autowired
	lateinit var service: Service

	@Test
	fun foo() {
		...
	}
}

@RunWith(SpringRunner::class) - it is used to tell the JUnit an entry point

@ActiveProfiles(“test”) - enable test profile if needed

@TestPropertySource(locations = [“classpath:application-test.properties”]) - read properties from application-test.properties file

Conclusion

We have described three scenarios of usage the Mockito with Spring boot and Kotlin. In particular, we described how to inject a mock with the help of @Mock and @InjectMocks, directly through a constructor of a bean and into an Application context.