I am parsing a Thymeleaf template using the following bean:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
@Service
public class ThymeleafProcessor {
private final TemplateEngine templateEngine;
@Autowired
public ThymeleafProcessor(TemplateEngine templateEngine) {
this.templateEngine = templateEngine;
}
public String process() {
final var templateResolvers = templateEngine.getTemplateResolvers();
System.out.println(templateResolvers);// Collection with one SpringResourceTemplateResolver
String process = templateEngine.process("test.html", new Context());
System.out.println(process); //Prints "Hello World"
return process;
}
}
The template is located in src/main/resources/templates and looks like this:
Hello World
So far everything works fine.
Now I want to write a unit test for the bean but this doesn't work:
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.thymeleaf.TemplateEngine;
import static org.junit.jupiter.api.Assertions.assertEquals;
@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = {
ThymeleafProcessor.class,
TemplateEngine.class,
})
@EnableConfigurationProperties
class ThymeleafProcessorTest {
@Autowired
private ThymeleafProcessor thymeleafProcessor;
@Autowired
private TemplateEngine templateEngine;
@Test
void doTest() {
System.out.println(templateEngine.getTemplateResolvers().size()); //this will return 0 in the test
var result = thymeleafProcessor.process();
assertEquals("Hello World", result);
}
}
Insetad of the expected String "Hello World" the String "test.html" is returned. The problem seems to be that no Template Resolver is available.
How does the test need to be configured in order to test the Thymeleaf template?
Those thymeleaf related beans are auto-configured by ThymeleafAutoConfiguration
which is enabled if any configuration class is annotated with @EnableAutoConfiguration
.
@SpringBootApplication
has this @EnableAutoConfiguration
, so when you start the app in normal way , ThymeleafAutoConfiguration
takes effect and define the related thymeleaf beans.
But now in test , you just specify to use ThymeleafProcessor
and TemplateEngine
as the configuration class to start the spring context. Neither @SpringBootApplication
nor @EnableAutoConfiguration
involved and so ThymeleafAutoConfiguration
does not take effect.
You can fix it by explicitly import ThymeleafAutoConfiguration
using @ImportAutoConfiguration
:
@SpringBootTest(classes = {ThymeleafProcessor.class})
@ImportAutoConfiguration(ThymeleafAutoConfiguration.class)
class ThymeleafProcessorTest {
}
I also tidy up the codes a bit :
@ExtendWith(SpringExtension.class)
is not required as it is already defined by @SpringBootTest
Do not need to define TemplateEngine
in @SpringBootTest
as it will be defined by ThymeleafAutoConfiguration
Most probably @EnableConfigurationProperties
is also not required.