如何在mvcmock单元测试

时间:2016-08-15 07:31:43

标签: java spring unit-testing authentication mockmvc

概述

我有一个注入身份验证的REST服务,我想使用mockmvc为它创建一个单元测试。我的RestController类如下:

import java.util.ArrayList;
import java.util.Collection;
import java.util.Set;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.blss.security.securityCommon.entities.SecureOperatorDetails;
import com.blss.security.securityGateway.providers.AccAuthenticationProvider;

import lombok.Data;

@RestController
@RequestMapping("/gateway")
public class AuthenticationDetailsRestController {

    @RequestMapping(value = "/userdetails", method = RequestMethod.GET)
    public UserDetailsResource currentUserName(Authentication authentication) {

        ArrayList<String> rolesList = new ArrayList<>();
        Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
        authorities
            .forEach(a -> {
                if (!a.getAuthority().startsWith(
                    AccAuthenticationProvider.CAD_TOKEN_AUTHORITY_PREFIX)) {
                    rolesList.add(a.getAuthority());
                }
            });

        SecureOperatorDetails operator = ((SecureOperatorDetails) authentication.getDetails());

        return new UserDetailsResource(
                authentication.getName(),
                operator.getOperator().getName(),
                operator.getOperator().getPermittedRetailerIds(),
                operator.getOperator().getStores(),
                operator.getOperator().getRetailerId(),
                operator.getDefaultStoreId(),
                operator.getDeviceId(),
                rolesList);
    }

    @Data
    static class UserDetailsResource {
        private final String username;
        private final String name;
        private final Set<String> retailerIds;
        private final Set<String> stores;
        private final String retailerId;
        private final String storeId;
        private final String deviceId;
        private final ArrayList<String> roles;
    }
}

问题

我不知道如何模拟身份验证并将其注入我的测试类中以避免 401 http例外 完整身份验证需要访问此资源

  

如果有人能帮我解决这个问题,我将不胜感激

2 个答案:

答案 0 :(得分:1)

您可以使用org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers

配置身份验证模拟

然后你应该把它作为下一个:

private MockMvc mockMvc;

@Override
protected void before() {
    this.mockMvc = webAppContextSetup(context).apply(SecurityMockMvcConfigurers.springSecurity()).build();
}

答案 1 :(得分:1)

我将以下代码段添加到我的测试类中,然后正确注入了身份验证:

  1. 添加此项以进行自定义身份验证:

    private MockMvc mockMvc;
    
    @Autowired
    private Authentication authentication;   
    @Bean
    public Authentication authentication() {
        Collection<GrantedAuthority> authorities = new ArrayList<>();
        authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
        UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken("customUsername", "customPassword", authorities); return authentication; }
    
    • 在设置方法中添加以下内容:

      @Before
      public void setUp()抛出异常{
          。SecurityContextHolder.getContext()setAuthentication(认证);     mockMvc = MockMvcBuilders.webAppContextSetup(context)                 .addFilter(new ShallowEtagHeaderFilter())                 。适用(documentationConfiguration(restDocumentation))                 。适用(springSecurity())                 。建立(); }

  2. 注意:

    • springSecurity()用于启用身份验证注入;否则,主类中的认证对象将为null(您为其编写的类)。

    • SecurityContextHolder.getContext()setAuthentication(认证)。用于注入自定义身份验证;否则,默认值将由springSecurity()

    • 注入