如何在JUnit中为Thymeleaf Test的TestExecutor传入模板上下文?
Thymeleaf Test:从JUnit代码传入模板上下文的方案
问题描述
我正在生成纯文本/HTML格式的邮件模板,并用thymeleaf-test进行测试。现在遇到的问题是:如何从外围Java JUnit代码中为模板传入所需的上下文?
现有测试代码如下:
@Test void testTheymeleaf() { TestExecutor executor = new TestExecutor(); executor.execute("classpath:mail/testResults.thtest"); Assertions.assertTrue(executor.isAllOK()); }
我知道可以在.thtest文件内部定义上下文,但由于上下文包含多个聚合对象,这种方式不可行;另外,上下文所需的数据已经在其他测试中存在,希望能直接复用。
解决方案
1. 自定义ITestContextFactory传入上下文
Thymeleaf Test的TestExecutor允许通过自定义ITestContextFactory注入外部上下文,步骤如下:
- 实现
ITestContextFactory接口,在createTestContext方法中构建并返回包含已有数据的上下文:
public class CustomTestContextFactory implements ITestContextFactory { private final Map<String, Object> contextData; // 传入已有的上下文数据 public CustomTestContextFactory(Map<String, Object> contextData) { this.contextData = contextData; } @Override public ITestContext createTestContext(ClassLoader classLoader, String testName) { // 创建基础上下文 DefaultTestContext testContext = new DefaultTestContext(classLoader, testName); // 把外部数据放入上下文变量 contextData.forEach(testContext::setVariable); return testContext; } }
- 在JUnit测试中,初始化
TestExecutor时传入这个自定义工厂,复用已有数据:
@Test void testThymeleaf() { // 从其他测试中获取已有的上下文数据(比如已构建好的聚合对象) Map<String, Object> existingContextData = getReusableContextData(); // 创建自定义上下文工厂 ITestContextFactory customFactory = new CustomTestContextFactory(existingContextData); // 初始化TestExecutor并传入工厂 TestExecutor executor = new TestExecutor(customFactory); executor.execute("classpath:mail/testResults.thtest"); Assertions.assertTrue(executor.isAllOK()); } // 模拟从其他测试复用数据的方法 private Map<String, Object> getReusableContextData() { Map<String, Object> data = new HashMap<>(); data.put("user", new User("张三", "zhangsan@example.com")); data.put("orderList", Arrays.asList(new Order(1, "商品A"), new Order(2, "商品B"))); // 其他聚合对象... return data; }
2. 直接通过TestExecutor的setVariable方法注入
如果不需要复杂的工厂,也可以直接用TestExecutor提供的setVariable方法逐个注入变量,适合变量不多的场景:
@Test void testThymeleaf() { TestExecutor executor = new TestExecutor(); // 复用已有测试中的数据 User existingUser = getExistingUser(); List<Order> existingOrders = getExistingOrders(); // 直接设置上下文变量 executor.setVariable("user", existingUser); executor.setVariable("orderList", existingOrders); executor.execute("classpath:mail/testResults.thtest"); Assertions.assertTrue(executor.isAllOK()); }
注意事项
- 确保
.thtest文件中不要重复定义上下文变量,避免冲突覆盖; - 如果使用Spring环境,也可以结合
SpringTestContextFactory来复用Spring容器中的Bean作为上下文数据。
内容的提问来源于stack exchange,提问作者Zian
相关产品推荐
相关产品推荐

