Spring @WithMockUser和request.IsUserInRole()

时间:2016-10-17 09:25:44

标签: java spring spring-mvc mockito

我正在使用:

request.IsUserInRole("ADMIN")

在我的一个控制器中确定对请求的响应。我试图在我的测试中模拟请求,如:

@Mock
private HttpServletRequest httpRequest;

并使用Springs注释@WithMockUser

@Test
@WithMockUser(roles={"USER, ADMIN"})
public void getAccountsTest() throws Exception {...}

两者都不起作用。

问题1:如何在JUnit测试中模拟request.IsUserInRole("ADMIN")

问题2:@WithMockUser对请求和request.IsUserInRole("ADMIN")有什么影响?

谢谢和最好的问候

----编辑----

“没有用”意味着我有一个测试方法:

@Test
@WithMockUser(username = "user", roles={"USER"})
public void getAccountsReturnForbiddenTest() throws Exception {
    mockMvc.perform(get("/accounts/"))
        .andExpect(status().isForbidden());
}

应返回403,因控制器而不允许:

@RequestMapping(method=RequestMethod.GET)
@PreAuthorize("hasRole('ADMIN')")
public ResponseEntity<PagedResources<AccountResource>> getAccounts(...){...}

但请求返回200,OK。

我正在使用Spring Boot 1.4.1。

----编辑2 ----

我的JUnit测试班:

@Transactional
@ContextConfiguration
public class AccountControllerTestDoc extends AbstractControllerTest {

    @InjectMocks
    private AccountController accountController;

    @Mock
    private AccountService accountService;

    private String uriBase = ""; 

    @Before
    public void setup() {
        // Initialize Mockito annotated components
        MockitoAnnotations.initMocks(this);
        // Prepare the Spring MVC Mock components for standalone testing
        setup(accountController);
    }

    @Test
    @WithMockUser(username = "user", roles={"USER"})
    public void getAccountsReturnForbiddenTest() throws Exception {
        String uri = uriBase + "/accounts";
        mockMvc.perform(get(uri))
            .andExpect(status().isForbidden());
    }

}

使用AbstractControllerTest:

@WebAppConfiguration
public abstract class AbstractControllerTest extends AbstractTest  {

    protected MockMvc mockMvc;

    @Autowired
    protected WebApplicationContext wac;

    protected void setup() {
        mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
    }

    protected void setup(BaseController controller) {
        mockMvc = MockMvcBuilders.standaloneSetup(controller))
                .build();
    }
}

和AbstractTest:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public abstract class AbstractTest {

    protected Logger LOG = LoggerFactory.getLogger(this.getClass());

}

----解决方案----

MockMvc standaloneSetup不了解Web应用程序上下文,因此不了解安全筛选器链。必须使用Web应用程序上下文和安全过滤器链设置MockMvc才能测试安全性方面。

这是我现在正在使用的解决方案,我编辑了AbstractControllerTest:

@WebAppConfiguration
public abstract class AbstractControllerTest extends AbstractTest  {

    protected MockMvc mockMvc;

    @Autowired
    protected WebApplicationContext wac;

    @Autowired
    FilterChainProxy springSecurityFilterChain;

    protected void setup() {
        mockMvc = MockMvcBuilders
            .webAppContextSetup(wac)
            .addFilters(springSecurityFilterChain)
            .build();
    }

    protected void setup(BaseController controller) {
        mockMvc = MockMvcBuilders.standaloneSetup(controller))
                .build();
    }
}

1 个答案:

答案 0 :(得分:2)

您应该在创建springSecurityFilterChain

时添加MockMvc
protected MockMvc mockMvc;

@Autowired
protected WebApplicationContext wac;

@Autowired
protected Filter springSecurityFilterChain;

protected void setup() {
    mockMvc = MockMvcBuilders
   .webAppContextSetup(wac)
   .addFilters(springSecurityFilterChain)
   .build();
}