跳到主要内容
版本:7.0.2

在 Spring MVC 测试中以用户身份运行测试

DeepSeek V3 中英对照 Mocking Users Running a Test as a User in Spring MVC Test

通常希望以特定用户身份运行测试。有两种简单的方法来设置用户:

在 Spring MVC 测试中使用 RequestPostProcessor 以用户身份运行

您有多种方式将用户与当前的 HttpServletRequest 关联起来。以下示例以用户名为 user、密码为 password、角色为 ROLE_USER 的用户(该用户无需实际存在)身份运行:

mvc
.perform(get("/").with(user("user")))
备注

该支持通过将用户与 HttpServletRequest 关联来实现。要将请求与 SecurityContextHolder 关联,你需要确保 SecurityContextPersistenceFilterMockMvc 实例相关联。你可以通过以下几种方式实现:

  • 调用 apply(springSecurity())

  • 将 Spring Security 的 FilterChainProxy 添加到 MockMvc

  • 当使用 MockMvcBuilders.standaloneSetup 时,手动将 SecurityContextPersistenceFilter 添加到 MockMvc 实例可能是有意义的

您可以轻松进行自定义。例如,以下配置将以用户身份运行(该用户无需实际存在),其用户名为"admin",密码为"pass",并拥有"ROLE_USER"和"ROLE_ADMIN"角色。

mvc
.perform(get("/admin").with(user("admin").password("pass").roles("USER","ADMIN")))

如果您希望使用自定义的 UserDetails,也可以轻松指定。例如,以下代码将使用指定的 UserDetails(该对象无需实际存在)来运行一个主体为指定 UserDetailsUsernamePasswordAuthenticationToken

mvc
.perform(get("/").with(user(userDetails)))

您可以使用以下方式以匿名用户身份运行:

mvc
.perform(get("/").with(anonymous()))

这在以默认用户身份运行,并希望以匿名用户身份处理一些请求时尤其有用。

如果你想要一个自定义的 Authentication(它不需要实际存在),你可以通过以下方式实现:

mvc
.perform(get("/").with(authentication(authentication)))

你甚至可以使用以下方式自定义 SecurityContext

mvc
.perform(get("/").with(securityContext(securityContext)))

我们还可以通过使用 MockMvcBuilders 的默认请求来确保每个请求都以特定用户身份运行。例如,以下代码将以用户名 "admin"、密码 "password" 和角色 "ROLE_ADMIN" 的用户身份运行(该用户无需实际存在):

mvc = MockMvcBuilders
.webAppContextSetup(context)
.defaultRequest(get("/").with(user("user").roles("ADMIN")))
.apply(springSecurity())
.build();

如果您发现自己在许多测试中都使用了相同的用户,建议将该用户移至一个方法中。例如,您可以在名为 CustomSecurityMockMvcRequestPostProcessors 的自定义类中指定以下内容:

public static RequestPostProcessor rob() {
return user("rob").roles("ADMIN");
}

现在你可以在测试中对 CustomSecurityMockMvcRequestPostProcessors 进行静态导入,并在测试中使用它:

import static sample.CustomSecurityMockMvcRequestPostProcessors.*;

...

mvc
.perform(get("/").with(rob()))

在 Spring MVC 测试中作为用户运行(使用注解)

作为使用 RequestPostProcessor 创建用户的替代方案,你可以使用方法安全测试中描述的注解。例如,以下代码将以用户名 "user"、密码 "password" 和角色 "ROLE_USER" 运行测试:

@Test
@WithMockUser
public void requestProtectedUrlWithUser() throws Exception {
mvc
.perform(get("/"))
...
}

或者,以下命令将以用户名 "user"、密码 "password" 和角色 "ROLE_ADMIN" 的用户身份运行测试:

@Test
@WithMockUser(roles="ADMIN")
public void requestProtectedUrlWithUser() throws Exception {
mvc
.perform(get("/"))
...
}