Spring Boot — Kotlin — Getting start unit testing
As a developer, I think writing unit testing on my own code is an essential part of my job role. Which ensure that my code is working properly and I feel confidence on that. But sometime, developers (including me) want to skip that due to busy timeline and pressure on work load.
Other thing is I saw lot of stuff on internet regarding unit testing, but some of them are not worked or not suited for my tasks.
So I want to show what are the mostly used things when writing unit testing for spring boot and Kotlin.
before that I put some technical explanations regarding unit testing. If you want you can read them. 😆
Unit testing is one of the major way of test the software, which will be tested the individual parts (methods, functions …etc) of the source code. Which categorize as automation test, which will be written by the developer. The key idea on that is logically split the software into smallest parts and writing the test cases based on that.
When the time of application deployment those test cases running independently, there may be come issues independently. Writing unit testing increases the source code quality and will be impacted to the code smell.
let me describe some annotations use in unit testing.
@SpringBootTest
SpringbootTests is an annotation, which can be mentioned in the spring boot based test classes. Which can be applied to identify the spring boot test class and help to load the spring boot application context, when there are no explicit @ContextConfiguration annotation defined. Also, which supports custom Environment properties to be determined using the properties attribute.
@MockBean
MockBean is a spring annotation which coming from spring boot test dependency.
@Test
Which is a Junit annotation use to defined test function and which should a void method.
@Autowired
Which is spring annotation, use to defined dependencies for the particular test class.
@BeforeEach
Junit annotation, use to add some configuration before run the test cases, like database connection open.
@AfterEach
Junit annotation, use to add some configuration which function run after the test cases, like database connection class.
Okay, Let’s do some practical scenario with Kotlin.
let’s assume you want to test a function that which returns sum of two integers.
import org.springframework.stereotype.Component@Component
class Calculator {
fun sumTwoInt(intOne: Int, intTwo: Int): Int {
return intOne+intTwo
}
}
Step 1:
create test class and test method, which class should be in the test package.
import org.junit.jupiter.api.Testinternal class CalculatorTest {
@Test
fun sumTwoInt() {
}
}
Step 2:
Add the @SpringBootTest annotation on top the test class
Step 3:
Inject the dependency for Calculator class using autowired annotation
@Autowired
private lateinit var calculator: Calculator
Step 4:
Write the test cases. For that you can use Assertion class, which provides many methods like assertEquals, assertTrue .
eg:
Assertions.assertEquals(4,calculator.sumTwoInt(1,3))
Like this way you can write many cases in same method.
Assertions.assertEquals(4,calculator.sumTwoInt(1,3))
Assertions.assertEquals(30,calculator.sumTwoInt(10,20))
Assertions.assertTrue(calculator.sumTwoInt(10,20) > 20)
Likewise you can verify the required method is working without any issues.
Complete Source
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Testimport org.junit.jupiter.api.Assertions.*
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest@SpringBootTest
internal class CalculatorTest { @Autowired
private lateinit var calculator: Calculator @Test
fun sumTwoInt() {
Assertions.assertEquals(4,calculator.sumTwoInt(1,3))
Assertions.assertEquals(30,calculator.sumTwoInt(10,20))
Assertions.assertTrue(calculator.sumTwoInt(10,20) > 20)
}
}
Other thing is most probably I want to mock some methods like database calling methods, external API calling methods. For that I use mock API, which is,
Mokito.when(<mock method>).thenReturn(<return result>)
Let’s see how to do that step by step:
Step 1:
Create mock dependency by using MockBean annotation
@MockBean
private lateinit var calculator: Calculator
Step 2:
Set function arguments and return value for required method.
Mockito.`when`(calculator.sumTwoInt(Mockito.anyInt(),Mockito.anyInt())).thenReturn(10)
In above I put any integer value as function arguments and what ever the integer arguments I set, should be returned 10. You can also put hard coded values as input arguments.
Step 3:
Check the result.
Assertions.assertEquals(10,calculator.sumTwoInt(1,3))
According to the mocking condition which should pass the test case.
Complete Source
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.mockito.Mockito
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.mock.mockito.MockBean
@SpringBootTest
internal class CalculatorTest {
@MockBean
private lateinit var calculator: Calculator
@Test
fun sumTwoInt() {
Mockito.`when`(calculator.sumTwoInt(Mockito.anyInt(),Mockito.anyInt())).thenReturn(10)
Assertions.assertEquals(10,calculator.sumTwoInt(1,3))
Assertions.assertEquals(10,calculator.sumTwoInt(10,20))
Assertions.assertTrue(calculator.sumTwoInt(10,20) > 5)
}
}
Happy coding …