As part of my Spring Boot app, I have a Thymeleaf HTML template rendering service:
@Service
class TemplateService(private val templateEngine: SpringTemplateEngine) {
fun renderTemplate(templateName: String, vars: Map<String, Any>): String =
templateEngine.process(templateName, Context()
}
A method in this service calls templateEngine.process
. I would like to test renderTemplate
on a concrete template to make sure that the template is rendered properly. Now, TemplateEngine
needs a resolver to render a template. Inspecting the source code I see that there's a default StringTemplateResolver
if there's nothing else configured. The resolver just treats the first argument of process
as a template string (instead of a template name which is what I want). Naturally then, this template resolver is used in my integration test which is set up like this:
@SpringJUnitConfig(classes = [SpringTemplateEngine::class])
class TemplateServiceIT @Autowired constructor(
springTemplateEngine: SpringTemplateEngine,
) {
private val templateService = TemplateService(springTemplateEngine)
}
This code "works" in the way that all the dependencies are correctly set up and I can create my TemplateService
instance. However, SpringTemplateEngine
is configured differently in this test than in the context of a real Spring Boot app because there an extra autoconfiguration is applied which sets up SpringResourceTemplateResolver
which correctly treats templateName
as a template name and not a template string.
Now to my question. I want to set up my test context in such a way that:
SpringTemplateEngine
(with SpringResourceTemplateResolver
)SpringBootTest
The correct way is to use @ImportAutoConfiguration
:
@SpringJUnitConfig(TemplateService::class)
// This auto-configures SpringTemplateEngine
@ImportAutoConfiguration(ThymeleafAutoConfiguration::class)
class TemplateServiceIT @Autowired constructor(private val templateService: TemplateService) {
...tests
}