Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add user role to request in Spring MVC Test Framework

Started studying Spring Test MVC Framework at the office today, it looks handy, but facing some serious trouble right off the bat. Spent a few hours googling, but couldn't find anything related to my issue.

Here's my very simple test class:

import static org.hamcrest.Matchers.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.web.context.WebApplicationContext;

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = WebAppContext.class)
public class ControllerTests {

    @Autowired
    private WebApplicationContext wac;

    private MockMvc mockMvc;

    @Before
    public void setup() {
        mockMvc = webAppContextSetup(wac).build();
    }

    @Test
    public void processFetchErrands() throws Exception {
        mockMvc.perform(post("/errands.do?fetchErrands=true"))
               .andExpect(status().isOk())
               .andExpect(model().attribute("errandsModel", allOf(
                   hasProperty("errandsFetched", is(true)),
                   hasProperty("showReminder", is(false)))));
    }
}

The test reaches the following controller, but fails on first if clause thanks to not being authorized properly.

@RequestMapping(method = RequestMethod.POST, params="fetchErrands")
public String processHaeAsioinnit(HttpSession session, HttpServletRequest request, ModelMap modelMap,
                                  @ModelAttribute(ATTR_NAME_MODEL) @Valid ErrandsModel model,
                                  BindingResult result, JopoContext ctx) {
  if (request.isUserInRole(Authority.ERRANDS.getCode())) {
    return Page.NO_AUTHORITY.getCode();
  }

  [...]
}

How do I add a user role for the MockHttpServletRequest that gets created by MockMvcRequestBuilders.post(), so that I can get past the authority check on my controller?

I know MockHttpServletRequest has a method addUserRole(String role), but since MockMvcRequestBuilders.post() returns a MockHttpServletRequestBuilder, I never get my hands on the MockHttpServletRequest and thus cannot call that method.

Checking the Spring source, MockHttpServletRequestBuilder has no methods related to user roles, nor is the MockHttpServletRequest.addUserRole(String role) ever called in that class, so I have no idea how to tell it to add a user role into the request.

All I can think of is adding a custom filter to filter chain and calling a custom HttpServletRequestWrapper from there that provides an implementation of isUserInRole(), but that seems a little extreme for such a case. Surely the framework should offer something more practical?

like image 758
t0mppa Avatar asked Jan 02 '14 13:01

t0mppa


1 Answers

I think I found an easier way

@Test
@WithMockUser(username = "username", roles={"ADMIN"})
public void testGetMarkupAgent() throws Exception {

    mockMvc.perform(get("/myurl"))
            .andExpect([...]);
}

You might need the following maven entry

    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-test</artifactId>
        <version>4.0.4.RELEASE</version>
        <scope>test</scope>
    </dependency>
like image 81
Tk421 Avatar answered Sep 29 '22 13:09

Tk421