I tried to write an integration test for my kotlin spring application. For this I am using the kotlintest framework. As I need to mock one of the beans in my application I also added mockk with the springmockk extension. After adding the springmockk extension the test no longer got executed.
I noticed this happens as soon as springmockk is added to the gradle testImplement dependencies, it does not even have to be imported in the application code itself.
buildscript {
ext.kotlin_version = '1.3.21'
ext.kotlintestVersion='3.4.2'
ext.spring_boot_version='2.1.4.RELEASE'
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:$springBoot_version")
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath("org.jetbrains.kotlin:kotlin-allopen:$kotlin_version")
}
}
...
dependencies {
...
testImplementation("org.springframework.boot:spring-boot-starter-test:$springBoot_version") {
testImplementation("io.kotlintest:kotlintest-runner-junit5:$kotlintestVersion")
testImplementation("io.kotlintest:kotlintest-extensions-spring:$kotlintestVersion")
testImplementation("io.mockk:mockk:1.9.3")
// testImplementation("com.ninja-squad:springmockk:2.0.0")
}
On github I found an issue which sadly has been closed already without any proper way of using these two frameworks together: https://github.com/Ninja-Squad/springmockk/issues/26
Edit:
This is an example test, which is working when using mockkito but not when using springmockk.
@ExtendWith(SpringExtension::class)
@SpringBootTest
@AutoConfigureMockMvc
@WithMockUser(authorities = ["ROLE_TESTUSER"])
internal class MockTest : AnnotationSpec() {
override fun listeners() = listOf(SpringListener)
@Autowired
lateinit var mockMvc: MockMvc
@MockkBean
lateinit var securityHelper: SecurityHelper
@Test
fun integrationTest() {
whenever(securityHelper.someFunction()).thenReturn("test")
mockMvc.perform(MockMvcRequestBuilders.get("/some/endpoint")
).andExpect(MockMvcResultMatchers.status().isOk)
}
}
./gradlew test --rerun-tasks
output:
> Configure project :
Property 'app.env' not found using profile dev: use -Papp.env=dev to define the environment for 'SPRING_PROFILES_ACTIVE'
> Task :compileKotlin
BUILD SUCCESSFUL in 56s
5 actionable tasks: 5 executed
To use @MockkBean
you need to add springmockk and remove mockito core from the spring-boot-starter-test in your gradle file like:
testImplementation("io.mockk:mockk:1.9.3")
testImplementation("com.ninja-squad:springmockk:2.0.2")
testImplementation("org.springframework.boot:spring-boot-starter-test") {
exclude(module = "mockito-core")
}
Then your bean should be mocked with:
@MockkBean
lateinit var securityHelper: SecurityHelper
You can mock the bean just using mockK by modifying the @TestConfiguration
and setting the profile of the mock Bean to be the same as the one used for your test:
@TestConfiguration
class ControllerTestConfig {
@Bean
@Profile("test")
fun securityHelper(): SecurityHelper {
val securityHelperMock: SecurityHelper = mockk(relaxed = true)
every { securityHelperMock.someFunction() } returns "test"
return securityHelperMock
}
}
You can force use the TestConfig by putting it in your @SpringBootTest
:
@SpringBootTest(
classes = [YourApplication::class, ControllerTestConfig::class]
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With