I am working on a kotlin spring application that makes use of Thymeleaf library for rendering templates from a file. Our application has to render the file using variables defined in a context, so this has to be mocked in an unit test.
Since the thymeleaf's engine classes have final methods, we have to make use of the interface that has the definition of the method we are using, which in this case is process.. So in the spring controller we are injecting ITemplateEngine from thymeleaf and we are creating a mock of that same interface in the unit test suite
// Example class to test
@Controller
class MyController(
private val templateEngine: ITemplateEngine
): ControllerAPI {
override fun getTemplateContent(): ResponseEntity<String> {
val context = Context()
context.setVariables(
mapOf(
Pair("scriptUrl", "localhost/assets/widget.min.js")
)
)
val content = templateEngine.process("scripts/controller.js", context)
return ResponseEntity<String>(content, HttpStatus.OK)
}
}
So for this example, the unit test is defined as follows:
@ExtendWith(MockitoExtension::class)
internal class ControllerTest {
lateinit var controller: MyController
@Mock
lateinit var templateEngine: ITemplateEngine
@BeforeEach
fun setup() {
controller = MyController(templateEngine)
}
@Test
fun getTemplateContent() {
val context = Context()
context.setVariables(
mapOf(
Pair("scriptUrl", "localhost/assets/widget.min.js")
)
)
`when`(templateEngine.process(eq("scripts/controller.js", refEq(context))))
.thenReturn("foobar")
val result = controller.getTemplateContent()
}
}
When running this test, i get the following error:
Strict stubbing argument mismatch. Please check:
- this invocation of 'process' method:
templateEngine.process(
"scripts/controller.js",
org.thymeleaf.context.Context@76cf841
);
-> at com.development.kotlin.spike.application.spike.gateway.web.MyController.getTemplateContent(MyController.kt:6)
- has following stubbing(s) with different arguments:
1. templateEngine.process(null, null)
At this point i'm scratching my head trying to understand why for some reason the stubbing has the parameters as null, i have tried not using ArgumentMatchers but the test fails due to the mock not being called since the context created in the test is a different instance than the one created by the mock.
I might be missing something, but i'd like to understand why the arguments are null, and if there's a good practice when it comes to mocking then i'd like to know.