Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java SpringWebMVCTest如何模拟身份验证?_Java_Spring_Spring Boot_Spring Security_Spring Security Rest - Fatal编程技术网

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链接以重现问题即使我这样做,我仍然会在
身份验证
上获取空指针,将主体作为控制器的参数并删除身份验证。