这是两全其美的方法,但是需要一些额外的设置.如果您具有返回UserDetails的自定义实现的自定义UserDetailsS​​ervice,并且不希望用户必须存在,则可以使用此方法.我会让您阅读有关此设置的文档,因为该文档冗长且文档齐全. 使用RequestPostProcessor 如果您不喜欢注释,则可以使用RequestPostProcessor.例如: 导入静态org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*;...@测试公共无效changePasswordWorks()引发异常{//发送密码更改请求PasswordChangeRepresentation passwordChange =新的PasswordChangeRepresentation(DefaultUsers.Admin.getPassword(),"12345678");mockMvc.perform(MockMvcRequestBuilders.request(HttpMethod.POST,"/password/change")//添加此行.with(user("admin").roles("USER","ADMIN")).content(新的ObjectMapper().writeValueAsString(passwordChange)).contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk());//检查密码是否已更改用户用户= this.userRepository.findByUsername(DefaultUsers.Admin.getEmail());Assert.assertEquals(user.getPassword(),"12345678");} I have a spring boot application which requires login for some actions. I am trying to test them using MockMvc, but it doesn't seem to work. I keep getting a HTTP response with status 403 (forbidden). Probably there is something wrong with the authentication part.I have tried following the documentation, but I wasn't able to get it working.This is my current testing code:@RunWith(SpringJUnit4ClassRunner.class)@SpringApplicationConfiguration(classes = {Application.class})@WebIntegrationTest("server.port = 8093")public class PasswordChangeTests { @Autowired private EmbeddedWebApplicationContext webApplicationContext; @Autowired private UserRepository userRepository; private MockMvc mockMvc; @Before public void setUp() throws Exception { this.mockMvc = MockMvcBuilders .webAppContextSetup(webApplicationContext) .apply(springSecurity()) .build(); } @Test public void changePasswordWorks() throws Exception { // Send password change request PasswordChangeRepresentation passwordChange = new PasswordChangeRepresentation(DefaultUsers.Admin.getPassword(), "12345678"); mockMvc.perform(MockMvcRequestBuilders.request(HttpMethod.POST, "/password/change") .content(new ObjectMapper().writeValueAsString(passwordChange)) .contentType(MediaType.APPLICATION_JSON) .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()); // Check that the password has been changed User user = this.userRepository.findByUsername(DefaultUsers.Admin.getEmail()); Assert.assertEquals(user.getPassword(), "12345678"); }}Sorry if I am missing something obvious. This is my first experience with spring boot. 解决方案 You need to specify which user you want to run the test as. You have a few options (each option is a link to the detailed documentation):@WithMockUserThis option will create a fake user (i.e. the user does not need to exist in a data store). The problem with this approach is if your application relies on a custom User implementation you may get class cast Exceptions. If you do not return a custom type from a custom UserDetailsService, then this solution should work fine. @Test @WithMockUser(username="admin",roles={"USER","ADMIN"}) public void changePasswordWorks() throws Exception {@WithUserDetailsIf you implemented a custom UserDetailsService that returns a custom implementation of UserDetails, this solution may work for you.For it to work you need to expose a UserDetailsService as a Bean and the user must exist. For example: @Test @WithUserDetails("admin") public void changePasswordWorks() throws Exception {@WithSecurityContextThis is the best of both worlds, but requires a little additional setup. If you have a custom UserDetailsService returning a custom implementation of UserDetails and do NOT want the user to necessarily have to exist you can use this method. I'll let you read the documentation on this setup as it is a bit more lengthy and well documented.Using a RequestPostProcessorIf annotations aren't your thing you can use a RequestPostProcessor. For example:import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*; ... @Test public void changePasswordWorks() throws Exception { // Send password change request PasswordChangeRepresentation passwordChange = new PasswordChangeRepresentation(DefaultUsers.Admin.getPassword(), "12345678"); mockMvc.perform(MockMvcRequestBuilders.request(HttpMethod.POST, "/password/change") // ADD this line .with(user("admin").roles("USER","ADMIN")) .content(new ObjectMapper().writeValueAsString(passwordChange)) .contentType(MediaType.APPLICATION_JSON) .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()); // Check that the password has been changed User user = this.userRepository.findByUsername(DefaultUsers.Admin.getEmail()); Assert.assertEquals(user.getPassword(), "12345678");} 这篇关于在需要身份验证的控制器上运行单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
07-29 21:10