我正在使用PowerMockRunner
spring-boot 应用程序进行测试。一切正常,但是当我的控制器操作定义包含someControllerMethod(..., Authentication auth, ...)
. 然后auth
为空,因此某些代码不起作用。
我尝试的是模拟Authentication
和SecurityContext
。想出了这样的东西
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(...);
}
...
}