Spring Boot+JUnit测试Vaadin受保护路由遇200状态码异常
问题分析与解决方案
核心问题
你遇到的200状态码问题,本质是两个关键错误导致:
- 测试注解冲突:
@SpringBootTest和@WebMvcTest是互斥的——@WebMvcTest是Spring MVC的切片测试注解,会覆盖@SpringBootTest的完整应用上下文,且完全不适配Vaadin的组件路由机制。 - MockMvc不适合Vaadin路由测试:Vaadin是单页应用,所有HTTP请求都会被VaadinServlet转发到应用入口页面,因此无论访问什么路径,MockMvc都会拿到200状态码。真正的权限校验是在Vaadin的路由导航阶段(通过
BeforeEnterObserver或@RolesAllowed注解触发),而非HTTP请求拦截阶段。
正确解决方案
方案1:使用Vaadin官方测试API验证路由权限
Vaadin提供了专门的Spring测试支持,直接模拟路由导航并校验权限:
@SpringBootTest @ActiveProfiles("test") @EnableVaadin @WithMockUser(roles = "USER") public class AuthorizationTest extends VaadinSpringTest { @Test public void testAccessingAdminRouteAsUser() { // 尝试导航到受保护路由 try { navigateTo("methodUsed/create"); // 若导航成功,说明权限校验失效,测试失败 fail("普通用户无法访问管理员路由"); } catch (AccessDeniedException e) { // 捕获到权限异常,测试通过 assertTrue(true); } // 额外验证是否被重定向到登录页(根据你的实际配置调整) String currentRoute = getCurrentRoute(); assertEquals("login", currentRoute); } }
方案2:单独测试组件的权限校验逻辑
因为你的组件实现了BeforeEnterObserver,可以直接测试beforeEnter方法的权限控制逻辑:
@ExtendWith(SpringExtension.class) @ActiveProfiles("test") public class MethodUsedEditViewPermissionTest { @Test @WithMockUser(roles = "USER") public void testUserCannotAccessAdminView() { MethodUsedEditView view = new MethodUsedEditView(); BeforeEnterEvent event = mock(BeforeEnterEvent.class); // 验证无权限用户会触发权限异常 assertThrows(AccessDeniedException.class, () -> view.beforeEnter(event)); } @Test @WithMockUser(roles = "ADMIN") public void testAdminCanAccessAdminView() { MethodUsedEditView view = new MethodUsedEditView(); BeforeEnterEvent event = mock(BeforeEnterEvent.class); // 验证管理员用户可正常进入,无异常抛出 view.beforeEnter(event); verify(event, never()).rerouteTo(anyString()); } }
必要配置检查
确保你的Spring Security配置正确生效:
- 开启方法级安全支持,让
@RolesAllowed注解生效:
@Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(jsr250Enabled = true) // 启用JSR-250注解(@RolesAllowed) public class SecurityConfiguration extends VaadinWebSecurity { @Override protected void configure(HttpSecurity http) throws Exception { super.configure(http); setLoginView("/login"); // 设置你的登录路由 } }
内容的提问来源于stack exchange,提问作者chris
相关产品推荐
相关产品推荐

