Java SpringWebMVCTest如何模拟身份验证?
我有一个具有以下方法的控制器。我从方法参数中获取Java SpringWebMVCTest如何模拟身份验证?,java,spring,spring-boot,spring-security,spring-security-rest,Java,Spring,Spring Boot,Spring Security,Spring Security Rest,我有一个具有以下方法的控制器。我从方法参数中获取身份验证,并使用它获取主体 @PatchMapping("/{employeeId}/present") public PersonalDevelopmentPlan savePresent(@PathVariable int employeeId, @RequestBody PersonalDevelopmentPlan personalDe
身份验证
,并使用它获取主体
@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)
谢谢 如果您最初在数据库中保留了一个用户(或者如果您在@PostConstruct中创建了这样的用户),则可以使用@WithUserDetails注释。 这将在身份验证是Spring Security的用户对象上使用主体
虽然
@WithMockUser
是一种非常方便的入门方式,但它可能并不适用于所有情况。例如,应用程序通常期望身份验证
主体为特定类型。这样做是为了应用程序可以将主体引用为自定义类型,并减少Spring安全性上的耦合
自定义主体通常由一个自定义UserDetails服务
多次返回,该服务返回一个同时实现UserDetails
和自定义类型的对象。对于这种情况,使用自定义UserDetailsService创建测试用户非常有用。这正是@WithUserDetails
所做的
我们可以创建自己的注释,该注释使用@WithSecurityContext创建我们想要的任何SecurityContext。例如,我们可能会创建一个名为@WithMockCustomUser的注释,名为
@WithSecurityContextFactory(factory=WithMockCustomUserSecurityContextFactory.class)
您是否使用UserDetails作为EmployeeDetails自定义了主体?@PatelRomil我不确定您的意思。我在我的UserDetails服务中覆盖loadUserByUsername
,并返回EmployeeDetails
(扩展了UserDetails
),如果这是您指的内容?是的,我指的是same@PatelRomil好的,那么我该怎么解决这个问题呢?我已经在答案中添加了细节,您可以将@与userdetails一起使用
,或将@与securitycontext一起使用
我尝试了您所说的内容,但没有解决。即使使用@WithUserDetails
我仍然在身份验证
@PatelCan您可以用最少的代码共享GitHub链接以重现问题即使我这样做,我仍然会在身份验证
上获取空指针,将主体作为控制器的参数并删除身份验证。