gpt4 book ai didi

java - Spring Boot @WebMvcTest 登录成功返回404

转载 作者:行者123 更新时间:2023-11-28 21:07:36 24 4
gpt4 key购买 nike

我正在学习如何测试我的 SpringBoot 应用。

现在我正在尝试通过为现有工作项目创建测试来学​​习。

我从我的 AdminHomeController 开始,它在管理员登录时管理主页:

@Controller
@RequestMapping("/admin/home")
public class AdminHomeController {

private UsuarioService usuarioService;

@Autowired
public AdminHomeController(UsuarioService usuarioService) {
this.usuarioService = usuarioService;
}

@RequestMapping(value={"", "/"}, method = RequestMethod.GET)
public ModelAndView admin_home(){
ModelAndView modelAndView = new ModelAndView();

Authentication auth = SecurityContextHolder.getContext().getAuthentication();
Usuario loggedUser = usuarioService.findUsuarioByUsername(auth.getName());
modelAndView.addObject("userFullName", loggedUser.getNombre() + " " + loggedUser.getApellido());
modelAndView.addObject("userGravatar", Utils.getGravatarImageLink(loggedUser.getEmail()));

modelAndView.addObject("totalUsuarios", usuarioService.getUsuariosCount());


modelAndView.setViewName("admin/home");
return modelAndView;
}
}

这是我的测试:

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = MyOwnProperties.class)
@WebMvcTest(AdminHomeController.class)
@Import(SecurityConfigurationGlobal.class)
public class AdminHomeControllerUnitTest {

@Autowired
private MockMvc mockMvc;

@MockBean
UsuarioService usuarioService;

@Autowired
MyOwnProperties myOwnProperties;

@MockBean
FacebookProfileService facebookProfileService;

@MockBean
MobileDeviceService mobileDeviceService;

@MockBean
PasswordEncoder passwordEncoder;

@MockBean
CustomAuthenticationProvider customAuthenticationProvider;


@Test
@WithMockUser(username = "user1", password = "pwd", authorities = "ADMIN")
public void shouldAllowAdminAccess() throws Exception{
when(usuarioService.findUsuarioByUsername("user1")).thenReturn(new Usuario());


mockMvc.perform(get("/admin/home"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(view().name("admin/home"));
}

}

我认为我的 SecurityConfig 的相关部分是:

@Override
protected void configure(HttpSecurity http) throws Exception {
http.
authorizeRequests()
.antMatchers("/", "/login", "/error/**", "/home").permitAll()
.antMatchers(
myOwnProperties.getSecurity().getJwtLoginURL(),
myOwnProperties.getSecurity().getFacebookLoginURL()).permitAll()
.antMatchers("/registration", "/registrationConfirm/**").permitAll()
.antMatchers("/resetPass", "/resetPassConfirm/**", "/updatePass").permitAll()
.antMatchers("/admin/**").hasAuthority(AUTHORITY_ADMIN)
.antMatchers("/user/**").hasAuthority(AUTHORITY_USER)
.anyRequest().authenticated()
.and()
.csrf().disable()
.formLogin()
.loginPage("/login")
.failureUrl("/login?error=true")
.successHandler(new CustomUrlAuthenticationSuccessHandler())
.usernameParameter("username")
.passwordParameter("password")
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/")
.and()
.exceptionHandling().accessDeniedPage("/403");
}

AUTHORITY_ADMIN 是“ADMIN”的静态最终定义。

由于我缺乏经验,我无法理解的是我的测试结果。

  • 如果我删除 @WithMockUser,我会按预期收到 401
  • 如果我将 @WithMockUser 与“ADMIN”以外的任何其他权限一起使用,我会收到 403,这也是预期的响应
  • 最后,如果我使用具有“ADMIN”权限的@WithMockUser,那么我会得到一个 404

如前所述,我的应用程序正在运行,如果以 ADMIN 身份登录,我只能访问/admin/home。

更新

运行这个其他类似的测试工作正常,但这个需要加载完整的 SpringBoot 应用程序。我认为这将是一个集成测试,我只想“单独”测试 Controller 。只有一个切片使用@WebMvcTest

@SpringBootTest
@AutoConfigureMockMvc
public class AdminHomeControllerTest {

@Autowired
private MockMvc mockMvc;


@MockBean
private UsuarioService usuarioService;

@Test
@WithMockUser(username = "user1", password = "pwd", authorities = "ADMIN")
public void shouldAllowAdminAccess() throws Exception{
when(usuarioService.findUsuarioByUsername(anyString())).thenReturn(new Usuario());


mockMvc.perform(get("/admin/home"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(view().name("admin/home"));
}
}

更新 2

我通过将 @ContextConfiguration(classes = MyOwnProperties.class) 更改为 @Import

使其通过

所以现在我的测试看起来像:

@RunWith(SpringRunner.class)
@WebMvcTest(AdminHomeController.class)
@Import({SecurityConfigurationGlobal.class, MyOwnProperties.class})
public class AdminHomeControllerUnitTest {
....... Same as before
}

我很高兴因为测试通过了,但是有人可以解释一下为什么吗?我在其他 SO 帖子中读到,要使用我自己的带有 @ConfigurationProperties 注释的自定义属性文件,我需要使用 @ContextConfiguration 注释。

最佳答案

我的问题的解决方案是将 @ContextConfiguration(classes = MyOwnProperties.class) 替换为 @Import

所以它会变成:

@RunWith(SpringRunner.class)
@WebMvcTest(AdminHomeController.class)
@Import({SecurityConfigurationGlobal.class, MyOwnProperties.class})
public class AdminHomeControllerUnitTest {
....... Same as before
}

更新 SpringBoot 2.x

我现在已将我的代码库迁移到 Spring Boot 2.4.1 并且此测试再次开始失败。经过反复试验,现在需要将 @Import 替换为 @ContextConfiguration

关于java - Spring Boot @WebMvcTest 登录成功返回404,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52084929/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com