如果登录成功,Spring Boot @WebMvcTest 返回 404 [英] Spring Boot @WebMvcTest returns 404 if success login

查看:96
本文介绍了如果登录成功,Spring Boot @WebMvcTest 返回 404的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习如何测试我的 SpringBoot 应用程序.

I'm learning how to Test my SpringBoot Apps.

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

Right now I'm trying to learn by creating test for an existing working project.

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

I started with my AdminHomeController that manages the Home when admins login:

@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 的相关部分是:

And I think that the relevan part of my SecurityConfig would be:

@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"的静态最终定义.

And AUTHORITY_ADMIN is a static final definition of "ADMIN".

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

What I can not understand due to my lack of experience are my test results.

  • 如果我删除 @WithMockUser,我会按预期得到 401
  • 如果我将 @WithMockUser 与ADMIN"以外的任何其他权限一起使用,我会收到 403,这也是预期的响应
  • 最后,如果我使用具有管理员"权限的 @WithMockUser 那么我会得到 404
  • If I remove the @WithMockUser I get a 401 as expected
  • If I use the @WithMockUser with ANY other authority than "ADMIN" I get a 403 that would also be the expected response
  • And finally if I use the @WithMockUser with "ADMIN" authority then I get a 404

如前所述,我的应用正在运行,如果以管理员身份登录,我只能访问/admin/home.

As said, my app is working and I can only access /admin/home if logged in as ADMIN.

运行另一个类似的测试工作正常,但这个需要加载完整的 SpringBoot 应用程序.我认为这将是一个集成测试,我只想单独"测试控制器.只有一个切片使用@WebMvcTest

Running this other similiar test works fine, but this one requieres the FULL SpringBoot app to load. I think it would be an integration test and I only want to test the controller "alone". Only a slice using @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

我通过为 @Import

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

So now my test looks like:

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

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

I'm happy because the test pass but can someone explain me why? I was reading in other SO post that to use my own custom properties files annotated with @ConfigurationProperties I need to use @ContextConfiguration annotation.

推荐答案

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

The solution to my problem was to replace @ContextConfiguration(classes = MyOwnProperties.class) for a @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.

UPDATE SpringBoot 2.x

I've now migrated my code base to Spring Boot 2.4.1 and this test start failing again. After trial and error, now the @Import need to be replaced with @ContextConfiguration.

这篇关于如果登录成功,Spring Boot @WebMvcTest 返回 404的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆