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

Spring Boot项目JUnit测试出现Thymeleaf SpringEL表达式异常

问题解决思路

核心原因

JUnit测试时没有模拟Spring Security的登录状态,导致Thymeleaf模板中#authentication对象为null,调用#authentication.principal.username时触发表达式求值异常。而手动测试时处于登录状态,Security上下文存在合法的Authentication对象,所以正常运行。

另外,手动配置WebMvcConfig添加Spring方言是多余操作——Spring Boot整合Thymeleaf+Spring Security时,已经自动注册了SpringSecurityDialect,手动配置反而可能破坏默认的模板解析逻辑,导致HTML文件无法访问。


解决方案

1. 修复JUnit测试:模拟登录状态

给测试方法添加Spring Security提供的注解,模拟登录用户,让Security上下文存在Authentication对象:

  • 如果只是简单模拟用户,用@WithMockUser:
@Test
@WithMockUser(username = "test-user@example.com") // 填写和transaction.buddySender.email匹配的用户名
void shouldReturnHomePage() throws Exception {
    // 你的测试逻辑,示例:
    mockMvc.perform(get("/"))
           .andExpect(status().isOk())
           .andExpect(view().name("home"));
}
  • 如果用了自定义UserDetails实现,用@WithUserDetails(需要你的UserDetailsService能加载指定用户):
@Test
@WithUserDetails(value = "test-user@example.com")
void shouldReturnHomePage() throws Exception {
    // 测试逻辑
}

2. 模板表达式做Null安全处理(可选,增强健壮性)

即使模拟登录,也可以给Thymeleaf表达式加Null判断,避免极端场景下的报错:

<!-- 原表达式 -->
<div th:if="#authentication.principal.username == transaction.buddySender.email">...</div>

<!-- 修改为Null安全版本 -->
<div th:if="${#authentication != null and #authentication.principal.username == transaction.buddySender.email}">...</div>

<!-- 或者用Elvis简化写法 -->
<div th:if="${(#authentication?.principal?.username) == transaction.buddySender.email}">...</div>

3. 恢复自动配置:删除自定义的WebMvcConfig方言配置

删掉你之前添加的SpringSecurityDialect Bean配置,让Spring Boot自动处理Thymeleaf方言注册,即可恢复HTML文件的访问:

// 删掉这段无用配置
@Bean
public SpringSecurityDialect springSecurityDialect() {
    return new SpringSecurityDialect();
}

内容的提问来源于stack exchange,提问作者Kévin Jovanovic

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 09:07:13