You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用@WebFluxTest测试Apache Freemarker整合代码失败问题

搞定WebFluxTest测试Freemarker视图控制器失败的问题

嘿,这个问题我之前也碰到过!你用@WebFluxTest测试返回Freemarker视图的控制器失败,核心原因是这个注解本来就不是为模板视图场景设计的——它默认只加载WebFlux的核心REST相关组件,完全不会自动配置Freemarker的视图解析器、模板引擎这些Bean。而你的ArticleController返回的是模板名称article/new,测试环境里没这些配置,自然处理不了这个请求。

给你两个靠谱的解决方案,按需选:

方案一:手动给测试加Freemarker视图配置

在测试类里嵌入一个配置类,手动注册Freemarker需要的视图解析器和配置Bean,让测试环境能识别视图返回:

@RunWith(SpringRunner.class)
@WebFluxTest(ArticleController.class)
// 导入我们自定义的视图配置
@Import(FreemarkerTestConfig.class)
public class ArticleControllerTest {

    @Autowired
    private WebTestClient webTestClient;

    @Test
    public void testNewArticleEndpoint() {
        webTestClient.get().uri("/new")
                .exchange()
                .expectStatus().isOk();
        // 要是想验证视图名称,还可以加断言,但WebTestClient不会实际渲染模板,只会确认请求能被正确映射到视图
    }

    // 内部静态配置类,专门给测试用的Freemarker配置
    @Configuration
    static class FreemarkerTestConfig {
        @Bean
        public FreeMarkerViewResolver freeMarkerViewResolver() {
            FreeMarkerViewResolver resolver = new FreeMarkerViewResolver();
            resolver.setPrefix("");
            resolver.setSuffix(".ftl");
            resolver.setContentType("text/html;charset=UTF-8");
            return resolver;
        }

        @Bean
        public FreeMarkerConfigurer freeMarkerConfigurer() {
            FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
            configurer.setTemplateLoaderPath("classpath:/templates/");
            // 这里可以加Freemarker的其他配置,比如编码之类的
            return configurer;
        }
    }
}

方案二:用@SpringBootTest做集成测试

如果你想测试更完整的流程(包括模板引擎的自动配置),直接换@SpringBootTest就行,它会加载整个应用上下文,自然包含Freemarker的所有配置:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class ArticleControllerTest {

    @Autowired
    private WebTestClient webTestClient;

    @Test
    public void testNewArticle() {
        webTestClient.get().uri("/new")
                .exchange()
                .expectStatus().isOk();
        // 要是需要验证渲染后的HTML内容,可以用expectBody(String.class)来断言
    }
}

两种方案怎么选?

  • 选方案一:测试启动更快,只加载必要的组件,适合做控制器逻辑的单元测试,专注验证请求映射和视图返回逻辑。
  • 选方案二:更贴近真实运行环境,适合做集成测试,能验证从请求到模板渲染的完整链路。

最后提一句:WebTestClient测试视图控制器时,默认不会渲染模板内容,只会确认请求能被正确处理、视图解析器能找到对应的模板路径。如果要验证渲染后的HTML,得用expectBody(String.class)来做字符串断言哦。

内容的提问来源于stack exchange,提问作者shazin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:16:29