Json Junit未在UsernameNotFoundException上调用@ControllerAdvice

Json Junit未在UsernameNotFoundException上调用@ControllerAdvice,json,spring,exception,junit,spring-security,Json,Spring,Exception,Junit,Spring Security,我正在为我的Rest应用程序编写一个集成测试。我编写了一个测试来检查accesDenied,它会引发一个UsernameNotFoundException,它应该这样做,但它不会在@ControllerAdvice类的异常之后返回一个JSON 代码在执行过程中正常工作,返回Json,在其他测试用例中,如AuthenticationFailed(AuthenticationFailed,whcih也由异常处理),Json在运行测试时返回。在这种情况下,json不会返回,可能是因为我有一个自定义的U

我正在为我的Rest应用程序编写一个集成测试。我编写了一个测试来检查accesDenied,它会引发一个UsernameNotFoundException,它应该这样做,但它不会在@ControllerAdvice类的异常之后返回一个JSON

代码在执行过程中正常工作,返回Json,在其他测试用例中,如AuthenticationFailed(AuthenticationFailed,whcih也由异常处理),Json在运行测试时返回。在这种情况下,json不会返回,可能是因为我有一个自定义的UserDetailsService

我在互联网上看到过,其他人只是测试是否引发了异常,并在当天致电。然而,我希望测试返回与执行相同的行为——Json。可能吗?我错过了什么

我尝试过类似问题的答案,但都不起作用,同样的行为也得到了回应

任何帮助都将不胜感激。Thx提前, 阿方索

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(类={TestConfig.class})
@WebAppConfiguration
公共类安全集成测试{
私有最终字符串SECURED_URI=“/users/1”;
私有最终字符串LOGIN_URI=“/LOGIN”;
@自动连线
私有WebApplicationContext wac;
@自动连线
私有过滤器ChainProxy springSecurityFilter;
@自动连线
CustomUserDetails服务CustomUserDetails服务;
@自动连线
用户控制器用户控制器;
私有MockMvc-MockMvc;
@以前
公共作废设置(){
this.mockMvc=MockMvcBuilders.webAppContextSetup(wac)
.addFilters(springSecurityFilter).alwaysDo(print()).build();
}
@试验
public void requireAuthentication()引发异常{
mockMvc.perform(
获取(受保护的URI).contentType(
MediaType.valueOf(Constants.REST_TYPE)))
.andExpect(状态().isUnauthorized())
.和期望(
content().contentType(
MediaType.valueOf(Constants.REST_TYPE)))
.andExpect(content().string(需要Jsons.AUTHENTICATION_));
}
@试验
public void authenticationFailed()引发异常{
mockMvc.perform(formLogin())
.andExpect(状态().isUnauthorized())
.和期望(
content().contentType(
MediaType.valueOf(Constants.REST_TYPE)))
.andExpect(content().string(Jsons.AUTHENTICATION_失败));
}
@试验
public void authenticationSuccess()引发异常{
mockMvc.perform(formLogin().user(“Ikos”).password(“Ikos”))
.andExpect(状态().isOk())
.和期望(
content().contentType(
MediaType.valueOf(Constants.REST_TYPE)))
.和期望(
content().string(
格式(Jsons.LOGIN,“Ikos”,“Ikos”);
}
@试验
public void accessgrated()引发异常{
UserDetails user=customUserDetailsService.loadUserByUsername(“Ikos”);
mockMvc.perform(
get(SECURED_URI).with(user(user)).contentType(
MediaType.valueOf(Constants.REST_TYPE)))
.andExpect(状态().isOk())
.和期望(
content().contentType(
MediaType.valueOf(Constants.REST_TYPE)))
.andExpect(content().string(RestDataFixture.defaultUserJSON());
}
@试验
public void accessDenied()引发异常{
UserDetails user=customUserDetailsService.loadUserByUsername(“Pedro”);
mockMvc.perform(
get(SECURED_URI).with(user(user)).contentType(
MediaType.valueOf(Constants.REST_TYPE)))
.andExpect(状态().isUnauthorized())
.和期望(
content().contentType(
MediaType.valueOf(Constants.REST_TYPE)))
.andExpect(content().string(需要Jsons.AUTHENTICATION_));
}
}
@配置
@ComponentScan(basePackages={“es.aekia.rest”})
@EnableWebMvc
公共类TestConfig{
}
@服务
公共类CustomUserDetailsService实现UserDetailsService{
@自动连线
私有UserDao UserDao;
@凌驾
公共用户详细信息loadUserByUsername(字符串用户名)
抛出UsernameNotFoundException{
用户;
试一试{
user=userDao.findByAlias(用户名);
if(user==null)
抛出新用户名NotFoundException(“未找到用户名”);
}捕获(数据访问异常){
抛出新用户名NotFoundException(“数据库错误”);
}
返回buildUserFromUserEntity(用户);
}
私有用户详细信息buildUserFromUserEntity(用户用户实体){
//将模型用户转换为spring安全用户
字符串username=userEntity.getAlias();
字符串password=userEntity.getPassword();
列表权限=新建ArrayList();
SimpleGrantedAuthority=新的SimpleGrantedAuthority(“角色”
+userEntity.getRole());
权限。添加(权限);
UserDetails springUser=new org.springframework.security.core.UserDetails.User(
用户名、密码、权限);
返回用户;
}
}
@控制器建议
公共类例外控制器{
@RequestMapping(products={Constants.REST_TYPE})
@ExceptionHandler({MissingServletRequestParameterException.class,
UnsatifiedServletRequestParameterException.class,
HttpRequestMethodNotSupportedException.class,
ServletRequestBindingException.class,
MethodArgumentNotValidException.class})
@ResponseStatus(值=HttpStatus.BAD_请求)
public@ResponseBody映射句柄请求异常(异常ex){
Map Map=Maps.newHashMap();
map.put(Constants.ERROR,Constants.REQUEST\u ERROR);
map.put(Constants.CAUSE,例如getMessage());
返回图;
}
@RequestMapping(products={Constants.REST_TYPE})
@异常处理程序(HttpMediaTypeNotSupportedException.class)
@ResponseStatus(值=HttpStatus。不支持的\媒体\类型)
public@ResponseBody映射handleUnsupportedMediaTypeException(
HttpMediaTypeNotSupportedException ex)引发IOException{
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { TestConfig.class })
@WebAppConfiguration
public class SecurityIntegrationTest {

    private final String SECURED_URI = "/users/1";
    private final String LOGIN_URI = "/login";

    @Autowired
    private WebApplicationContext wac;

    @Autowired
    private FilterChainProxy springSecurityFilter;

    @Autowired
    CustomUserDetailsService customUserDetailsService;

    @Autowired
    UserController userController;

    private MockMvc mockMvc;

    @Before
    public void setup() {
    this.mockMvc = MockMvcBuilders.webAppContextSetup(wac)
        .addFilters(springSecurityFilter).alwaysDo(print()).build();
    }

    @Test
    public void requiresAuthentication() throws Exception {
    mockMvc.perform(
        get(SECURED_URI).contentType(
            MediaType.valueOf(Constants.REST_TYPE)))
        .andExpect(status().isUnauthorized())
        .andExpect(
            content().contentType(
                MediaType.valueOf(Constants.REST_TYPE)))
        .andExpect(content().string(Jsons.AUTHENTICATION_REQUIRED));
    }

    @Test
    public void authenticationFailed() throws Exception {
    mockMvc.perform(formLogin())
        .andExpect(status().isUnauthorized())
        .andExpect(
            content().contentType(
                MediaType.valueOf(Constants.REST_TYPE)))
        .andExpect(content().string(Jsons.AUTHENTICATION_FAILED));
    }

    @Test
    public void authenticationSuccess() throws Exception {
    mockMvc.perform(formLogin().user("Ikos").password("Ikos"))
        .andExpect(status().isOk())
        .andExpect(
            content().contentType(
                MediaType.valueOf(Constants.REST_TYPE)))
        .andExpect(
            content().string(
                String.format(Jsons.LOGIN, "Ikos", "Ikos")));
    }

    @Test
    public void accessGranted() throws Exception {
    UserDetails user = customUserDetailsService.loadUserByUsername("Ikos");

    mockMvc.perform(
        get(SECURED_URI).with(user(user)).contentType(
            MediaType.valueOf(Constants.REST_TYPE)))
        .andExpect(status().isOk())
        .andExpect(
            content().contentType(
                MediaType.valueOf(Constants.REST_TYPE)))
        .andExpect(content().string(RestDataFixture.defaultUserJSON()));
    }

    @Test
    public void accessDenied() throws Exception {
    UserDetails user = customUserDetailsService.loadUserByUsername("Pedro");

    mockMvc.perform(
        get(SECURED_URI).with(user(user)).contentType(
            MediaType.valueOf(Constants.REST_TYPE)))
        .andExpect(status().isUnauthorized())
        .andExpect(
            content().contentType(
                MediaType.valueOf(Constants.REST_TYPE)))
        .andExpect(content().string(Jsons.AUTHENTICATION_REQUIRED));
    }
}

@Configuration
@ComponentScan(basePackages = { "es.aekia.rest" })
@EnableWebMvc
public class TestConfig {
}

@Service
public class CustomUserDetailsService implements UserDetailsService {

    @Autowired
    private UserDao userDao;

    @Override
    public UserDetails loadUserByUsername(String username)
        throws UsernameNotFoundException {
    User user;
    try {
        user = userDao.findByAlias(username);
        if (user == null)
        throw new UsernameNotFoundException("user name not found");

    } catch (DataAccessException e) {
        throw new UsernameNotFoundException("database error");
    }

    return buildUserFromUserEntity(user);
    }

    private UserDetails buildUserFromUserEntity(User userEntity) {
    // convert model user to spring security user
    String username = userEntity.getAlias();
    String password = userEntity.getPassword();

    List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
    SimpleGrantedAuthority authority = new SimpleGrantedAuthority("ROLE_"
        + userEntity.getRole());
    authorities.add(authority);

    UserDetails springUser = new org.springframework.security.core.userdetails.User(
        username, password, authorities);
    return springUser;
    }
}

@ControllerAdvice
public class ExceptionController {

    @RequestMapping(produces = { Constants.REST_TYPE })
    @ExceptionHandler({ MissingServletRequestParameterException.class,
        UnsatisfiedServletRequestParameterException.class,
        HttpRequestMethodNotSupportedException.class,
        ServletRequestBindingException.class,
        MethodArgumentNotValidException.class })
    @ResponseStatus(value = HttpStatus.BAD_REQUEST)
    public @ResponseBody Map<String, Object> handleRequestException(Exception ex) {
    Map<String, Object> map = Maps.newHashMap();
    map.put(Constants.ERROR, Constants.REQUEST_ERROR);
    map.put(Constants.CAUSE, ex.getMessage());
    return map;
    }

    @RequestMapping(produces = { Constants.REST_TYPE })
    @ExceptionHandler(HttpMediaTypeNotSupportedException.class)
    @ResponseStatus(value = HttpStatus.UNSUPPORTED_MEDIA_TYPE)
    public @ResponseBody Map<String, Object> handleUnsupportedMediaTypeException(
        HttpMediaTypeNotSupportedException ex) throws IOException {
    Map<String, Object> map = Maps.newHashMap();
    map.put(Constants.ERROR, Constants.UNSUPPORTED_MEDIA_TYPE);
    map.put(Constants.CAUSE, ex.getLocalizedMessage());
    map.put(Constants.SUPPORTED, ex.getSupportedMediaTypes());
    return map;
    }

    @RequestMapping(produces = { Constants.REST_TYPE })
    @ExceptionHandler({ AccessDeniedException.class,
        UsernameNotFoundException.class })
    @ResponseStatus(value = HttpStatus.UNAUTHORIZED)
    public @ResponseBody Map<String, Object> handleAccesDeniedException(
        Exception ex) {
    Map<String, Object> map = Maps.newHashMap();
    map.put(Constants.ERROR, Constants.ACCESS_DENIED);
    map.put(Constants.CAUSE, ex.getMessage());
    return map;
    }

    @RequestMapping(produces = { Constants.REST_TYPE })
    @ExceptionHandler(Exception.class)
    @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
    public @ResponseBody Map<String, Object> handleUncaughtException(
        Exception ex) throws IOException {
    Map<String, Object> map = Maps.newHashMap();
    map.put(Constants.ERROR, Constants.UNKNOWN_ERROR);
    if (ex.getCause() != null) {
        map.put(Constants.CAUSE, ex.getCause().getMessage());
    } else {
        map.put(Constants.CAUSE, ex.getMessage());
    }
    return map;
    }

}

@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private RestAuthenticationEntryPoint restAuthenticationEntryPoint;
    @Autowired
    private RestAccessDeniedHandler restAccessDeniedHandler;

    @Autowired
    private RestAuthSuccessHandler restAuthSuccessHandler;
    @Autowired
    private RestAuthFailureHandler restAuthFailureHandler;
    @Autowired
    private RestLogoutSuccessHandler restLogoutSuccessHandler;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
    http.csrf()
        .disable()
        /*
         * .authenticationProvider(authenticationProvider())
         */
        .exceptionHandling()
        .authenticationEntryPoint(restAuthenticationEntryPoint)
        .accessDeniedHandler(restAccessDeniedHandler)
        .and()
        .formLogin()
        .permitAll()
        .loginProcessingUrl("/login")
        // .usernameParameter(USERNAME)
        // .passwordParameter(PASSWORD)
        .successHandler(restAuthSuccessHandler)
        .failureHandler(restAuthFailureHandler).and()
        .logout()
        .permitAll()
        // .logoutRequestMatcher(new AntPathRequestMatcher(LOGIN_PATH,
        // "DELETE"))
        .logoutSuccessHandler(restLogoutSuccessHandler).and()
        .sessionManagement().maximumSessions(1);

    // .logoutSuccessUrl("/logout").and()
    /*
     * .sessionManagement() .sessionCreationPolicy (SessionCreationPolicy
     * .STATELESS).and()
     */

    //
    http.authorizeRequests().antMatchers(HttpMethod.POST, "/login")
        .permitAll().antMatchers(HttpMethod.POST, "/logout")
        .authenticated().antMatchers(HttpMethod.GET, "/users")
        .permitAll().antMatchers(HttpMethod.GET, "/users/**")
        .hasAnyRole("USER", "ADMIN")
        .antMatchers(HttpMethod.POST, "/**").hasRole("ADMIN")
        .antMatchers(HttpMethod.PUT, "/**").hasRole("ADMIN")
        .antMatchers(HttpMethod.PATCH, "/**").hasRole("ADMIN")
        .antMatchers(HttpMethod.DELETE, "/**").hasRole("ADMIN");
    // .anyRequest().anonymous();
    }
}