В моем текущем проекте у меня есть несколько фрагментов Thymeleaf, хранящихся под деревом src src/main/resources/templates/fragments
. В моем наборе тестов у меня есть несколько тестовых шаблонов, которые будут извлекать отдельные фрагменты, чтобы я мог обработать их и сравнить выходные данные с некоторыми тестовыми выходными файлами. Они расположены в src/test/resources/test-templates/input
и выглядят следующим образом:
титульный и субтитры испытаний input.html
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">>
<body>
<table
th:replace="~{fragments/titleAndSubtitle :: titleAndSubtitleTable(titleText = 'Test Title', subtitleText = 'Test Subtitle')}"></table>
</body>
</html>
и фрагмент titleAndSubtitle выглядит следующим образом:
titleAndSubtitle.html
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<body>
<table class="fragment" th:fragment="titleAndSubtitleTable(titleText, subtitleText)">
<tr>
<td class="title">[[${titleText}]]</td>
</tr>
<tr>
<td class="subtitle">[[${subtitleText}]]</td>
</tr>
</table>
</body>
</html>
и мой тестовый конфигурационный класс thymeleaf выглядит следующим образом:
ThymeleafTestConfiguration.java
@Configuration
public class ThymeleafTestConfiguration extends WebMvcConfigurerAdapter implements ApplicationContextAware {
private static final String TEST_TEMPLATE_DIRECTORY = "classpath:/test-templates/input/";
private static final String TEMPLATE_SUFFIX = ".html";
@Autowired
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
/**
* THYMELEAF: View Resolver - implementation of Spring's ViewResolver
* interface.
*
* @return ViewResolver
*/
@Bean
public ViewResolver viewResolver() {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine());
return viewResolver;
}
/**
* THYMELEAF: Template Engine (Spring4-specific version).
*
* @return SpringTemplateEngine
*/
@Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setEnableSpringELCompiler(true);
templateEngine.addTemplateResolver(templateResolver());
return templateEngine;
}
/**
* THYMELEAF: Template Resolver for test templates.
*
* @return TemplateResolver
*/
private ITemplateResolver templateResolver() {
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
templateResolver.setApplicationContext(applicationContext);
templateResolver.setPrefix(TEST_TEMPLATE_DIRECTORY);
templateResolver.setSuffix(TEMPLATE_SUFFIX);
templateResolver.setTemplateMode(TemplateMode.HTML);
templateResolver.setOrder(1);
return templateResolver;
}
}
Мне не удалось правильно сконфигурировать распознаватель и механизм шаблонов Thymeleaf, чтобы он мог найти тестовое входное поле и по-прежнему разрешать выражение фрагмента, т.е. извлекать фрагмент из дерева src. Вместо этого я решил скопировать содержимое моего каталога фрагментов в дереве src во временную папку - src/test/resources/test-templates/input/fragments
, при этом идея заключалась в том, что фрагменты временно помещаются в тестовый ресурс, чтобы преобразователь шаблонов тимилиста мог успешно найти и извлечь их, перетащите их в шаблон теста для обработки, и после запуска всех тестов временный каталог будет удален. Я могу успешно скопировать каталог и его содержимое в дерево тестов, но получаю сообщения об ошибках типа:
org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "class path resource [test-templates/input//fragments/titleAndSubtitle.html]" - line 5, col 9)
//etc
Caused by: java.io.FileNotFoundException: class path resource [test-templates/input/fragments/titleAndSubtitle.html] cannot be opened because it does not exist
Это похоже на ошибки, которые я видел, когда все еще возился с распознавателями шаблонов. Тест выглядит следующим образом:
FragmentTest.java
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = ThymeleafTestConfiguration.class)
public class ClaimSnapshotFragmentTest {
private static File sourceFragmentDirectory = new File("src/main/resources/templates/fragments");
private static File tempFragmentDirectory = new File("src/test/resources/test-templates/input/fragments");
@BeforeClass
public static void setupClass() throws Exception {
if(tempFragmentDirectory.exists()) {
deleteDirectory(tempFragmentDirectory);
}
copyDirectory(sourceFragmentDirectory, tempFragmentDirectory);
}
@AfterClass
public static void teardownClass() throws Exception {
if(tempFragmentDirectory.exists()) {
deleteDirectory(tempFragmentDirectory);
}
}
@Autowired
private SpringTemplateEngine templateEngine;
@Test
public void test_titleAndSubtitle_fragmentParsedWithData() throws Exception {
final String expected = FileUtils.getFileFromFolderAsString("title-and-subtitle-test-expected-output.html",
FOLDER_TEST_TEMPLATES_OUTPUT);
final String actual = templateEngine.process("title-and-subtitle-test-input", new Context());
final Diff diff = DiffBuilder
.compare(expected)
.withTest(actual)
.checkForSimilar()
.normalizeWhitespace()
.build();
assertThat(diff.hasDifferences()).isFalse();
}
Я что-то упустил в конфигурации Thymeleaf? Я проверил с помощью кода и вручную, что каталог фрагментов создан, содержит соответствующий шаблон фрагмента и успешно удален после выполнения тестов, но я все еще получаю сообщение об ошибке, что файлы не существуют. Примечание: я использую Thymeleaf версии 3.0.9.RELEASE с версией диалекта Thymeleaf версии 2.3.0. Приложение запускает Thymeleaf в «автономном режиме» и используется в основном для создания тел электронной почты путем объединения данных, полученных MQ, и обработки их в шаблоне. Методы copyDirectory и deleteDirectory из класса Apache Commons FileUtils