Spring WebMvcTest 如何模拟身份验证?



我有一个具有以下方法的控制器。我从方法参数中获取Authentication并使用它来获取主体。

@PatchMapping("/{employeeId}/present")
public PersonalDevelopmentPlan savePresent(@PathVariable int employeeId,
@RequestBody PersonalDevelopmentPlan personalDevelopmentPlan,
Authentication authentication) {
EmployeeDetails details = (EmployeeDetails) authentication.getPrincipal();
return pdpService.savePresent(employeeId, personalDevelopmentPlan, details.getEmployee().getId());
}

然后,我使用@WebMvcTest有了这个测试用例

@Test
@WithMockUser
public void testSavePresent_returns_result_from_service() throws Exception {
PersonalDevelopmentPlan pdp = new PersonalDevelopmentPlan();
pdp.setEmployee(EMPLOYEE_ID);
given(service.savePresent(eq(EMPLOYEE_ID), any(), anyInt())).willReturn(pdp);
mvc.perform(patch(URL_WITH_ID + "/present").secure(true)
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(pdp)))
.andExpect(status().isOk())
.andExpect(jsonPath("$.employee", Matchers.is(EMPLOYEE_ID)));
}

但是,当我运行它时,我在以下行得到一个NullPointerException

EmployeeDetails details = (EmployeeDetails) authentication.getPrincipal();

因为身份验证为空。我已经用@MockUser注释了测试,但身份验证仍然为空。如何在控制器方法的参数中模拟身份验证?

我的测试带有注释@AutoConfigureMockMvc(addFilters = false)

谢谢!

@WithMockUser这将使用身份验证上的主体是 Spring Security 的用户对象

<小时 />

@WithUserDetails

虽然@WithMockUser是一种非常方便的入门方法,但它可能并非在所有情况下都有效。例如,应用程序通常期望Authentication主体是特定类型。这样做是为了使应用程序可以将主体称为自定义类型,并减少 Spring 安全性上的耦合。

自定义主体通常由自定义UserDetailsService返回,该返回同时实现UserDetails和自定义类型的对象。对于此类情况,使用自定义用户详细信息服务创建测试用户非常有用。这正是@WithUserDetails所做的。

<小时 />

@WithSecurityContext

我们可以创建自己的注释,使用该注释@WithSecurityContext来创建我们想要的任何SecurityContext。例如,我们可以创建一个名为 @WithMockCustomUser 的注释作为@WithSecurityContext(factory = WithMockCustomUserSecurityContextFactory.class)

如果最初在数据库中保留了用户(或者在 @PostConstruct 中创建用户),则可以使用 @WithUserDetails 注释。

相关内容

  • 没有找到相关文章

最新更新