0

我正在使用PowerMockRunnerspring-boot 应用程序进行测试。一切正常,但是当我的控制器操作定义包含someControllerMethod(..., Authentication auth, ...). 然后auth为空,因此某些代码不起作用。

我尝试的是模拟AuthenticationSecurityContext。想出了这样的东西

    private void mockSecurity() {
        Authentication authentication = mock(Authentication.class);
        SecurityContext securityContext = mock(SecurityContext.class);

        List<SimpleGrantedAuthority> authorities = Arrays.asList(new SimpleGrantedAuthority("USER"));
        User mockedUser = new User("testuser", "passwordtest", authorities);

        when(securityContext.getAuthentication()).thenReturn(authentication);
        SecurityContextHolder.setContext(securityContext);
        when(SecurityContextHolder.getContext().getAuthentication().getDetails()).thenReturn(mockedUser);
        when(SecurityContextHolder.getContext().getAuthentication().getName()).thenReturn(mockedUser.getUsername());
    }

现在这些模拟工作,如果我的代码使用SecurityContextHolder.getContext().getAuthentication()访问身份验证的方法,但不是自动注入的(可能是因为在创建控制器模拟时它还没有模拟)。

有什么想法可以模拟注入Authentication的代码,因此不需要更改代码?spring-security-test@MockWithUser得到相同的结果。

测试的相关部分如下所示,

@RunWith(PowerMockRunner.class)
public class UserControllerTest {
    @InjectMocks
    UserController userController;

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
        mockMvc = standaloneSetup(userController).build();
    }

    @Test
    public void getUserDetails() {
        mockSecurity();
        mockMvc.perform(...).andExpect(...);
    }
}

根据 pvpkiran 的要求编辑控制器代码

@RequestMapping(...)
public void getDetails(@PathVariable String id, Authentication auth) {
    UserDetails loadedDetails = userService.getUserDetails(id);
    if (!loadedDetails.getUserId().equals(auth.getName())) {
         throw new Exception(...);
    }
    ...
}
4

0 回答 0