以用户身份在 Spring MVC Test 中运行测试
通常,以特定用户身份运行测试是很有必要的。有两种简单的方法来设置用户:
在 Spring MVC 测试中使用 RequestPostProcessor 以用户身份运行
你有多种选项可以将用户与当前的 HttpServletRequest
关联起来。以下示例以用户名为 user
、密码为 password
且角色为 ROLE_USER
的用户身份运行(该用户不需要实际存在):
- Java
- Kotlin
mvc
.perform(get("/").with(user("user")))
mvc.get("/") {
with(user("user"))
}
支持通过将用户关联到 HttpServletRequest
来实现。要将请求与 SecurityContextHolder
关联,你需要确保 SecurityContextPersistenceFilter
与 MockMvc
实例关联。你可以通过以下几种方式来实现:
-
将 Spring Security 的
FilterChainProxy
添加到MockMvc
-
当使用
MockMvcBuilders.standaloneSetup
时,手动将SecurityContextPersistenceFilter
添加到MockMvc
实例可能是有意义的
你可以轻松进行自定义。例如,以下将以用户名为 "admin"、密码为 "pass" 且具有 "ROLE_USER" 和 "ROLE_ADMIN" 角色的用户身份运行(该用户不需要存在)。
- Java
- Kotlin
mvc
.perform(get("/admin").with(user("admin").password("pass").roles("USER","ADMIN")))
mvc.get("/admin") {
with(user("admin").password("pass").roles("USER","ADMIN"))
}
如果你有一个自定义的 UserDetails
并希望使用它,你也可以轻松指定。例如,以下代码将使用指定的 UserDetails
(不需要实际存在)来运行,并使用一个具有指定 UserDetails
为主体的 UsernamePasswordAuthenticationToken
:
- Java
- Kotlin
mvc
.perform(get("/").with(user(userDetails)))
mvc.get("/") {
with(user(userDetails))
}
您可以使用以下命令以匿名用户身份运行:
- Java
- Kotlin
mvc
.perform(get("/").with(anonymous()))
mvc.get("/") {
with(anonymous())
}
这在你以默认用户运行并希望以匿名用户身份处理一些请求时特别有用。
如果你想要一个自定义的 Authentication
(不需要已经存在),你可以按照以下方式进行:
- Java
- Kotlin
mvc
.perform(get("/").with(authentication(authentication)))
mvc.get("/") {
with(authentication(authentication))
}
你甚至可以使用以下方法来自定义 SecurityContext
:
- Java
- Kotlin
mvc
.perform(get("/").with(securityContext(securityContext)))
mvc.get("/") {
with(securityContext(securityContext))
}
我们还可以通过使用 MockMvcBuilders
的默认请求来确保每个请求都以特定用户身份运行。例如,以下将以用户名 "admin"、密码 "password" 和角色 "ROLE_ADMIN" 的用户身份运行(该用户不必实际存在):
- Java
- Kotlin
mvc = MockMvcBuilders
.webAppContextSetup(context)
.defaultRequest(get("/").with(user("user").roles("ADMIN")))
.apply(springSecurity())
.build();
mvc = MockMvcBuilders
.webAppContextSetup(context)
.defaultRequest<DefaultMockMvcBuilder>(get("/").with(user("user").roles("ADMIN")))
.apply<DefaultMockMvcBuilder>(springSecurity())
.build()
如果你发现你在许多测试中都使用了相同的用户,建议将该用户移到一个方法中。例如,你可以在名为 CustomSecurityMockMvcRequestPostProcessors
的类中指定以下内容:
- Java
- Kotlin
public static RequestPostProcessor rob() {
return user("rob").roles("ADMIN");
}
fun rob(): RequestPostProcessor {
return user("rob").roles("ADMIN")
}
现在你可以在测试中对 CustomSecurityMockMvcRequestPostProcessors
进行静态导入并使用它:
- Java
- Kotlin
import static sample.CustomSecurityMockMvcRequestPostProcessors.*;
...
mvc
.perform(get("/").with(rob()))
import sample.CustomSecurityMockMvcRequestPostProcessors.*
//...
mvc.get("/") {
with(rob())
}
在Spring MVC测试中使用注解以用户身份运行
作为使用 RequestPostProcessor
创建用户的替代方法,你可以使用在 测试方法安全性 中描述的注解。例如,以下代码将以用户名 "user"、密码 "password" 和角色 "ROLE_USER" 的用户身份运行测试:
- Java
- Kotlin
@Test
@WithMockUser
public void requestProtectedUrlWithUser() throws Exception {
mvc
.perform(get("/"))
...
}
@Test
@WithMockUser
fun requestProtectedUrlWithUser() {
mvc
.get("/")
// ...
}
或者,以下将使用用户名为 "user"、密码为 "password" 以及角色为 "ROLE_ADMIN" 的用户运行测试:
- Java
- Kotlin
@Test
@WithMockUser(roles="ADMIN")
public void requestProtectedUrlWithUser() throws Exception {
mvc
.perform(get("/"))
...
}
@Test
@WithMockUser(roles = ["ADMIN"])
fun requestProtectedUrlWithUser() {
mvc
.get("/")
// ...
}