Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring MockMvc - request parameter list

I'm trying to test a couple of controller endpoints with MockMvc and I'm having a bit of trouble (be kind, I'm new...). The simple endpoint that consumes a string as it's parameter works fine, but the slightly more complicated endpoint that consumes a list of strings is not happy and throws an exception; can anybody point out what I'm doing wrong?

@RestController
@RequestMapping("/bleh")
public class Controller
{
    @Autowired
    private DataService dataService

    @RequestMapping(value = "/simple", method = RequestMethod.GET)
    public String simple(String name) 
    { 
        return dataService.getSomeData(name) 
    }

    @RequestMapping(value = "/complicated", method = RequestMethod.GET)
    public String complex(List<String> names)
    { 
        return dataService.getSomeOtherData(names) 
    }
}

-

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class HealthControllerTests extends Specification
{
    def dataServiceMock;
    def testController;
    def mockMvc;


    def setup(){
        dataServiceMock = Mock(DataService)
        dataServiceMock.getSomeData >> "blaah"
        testController = new Controller(dataService: dataServiceMock)
        mockMvc = MockMvcBuilders.standaloneSetup(testController).build();
    }

    def "working test"
        when:
        def response = MockMvc.perform(get("/simple").param("name", "tim"))
                .andReturn()
                .getResponse();

        then:
        response.status == OK.value();
        response.contentAsString == "blaah"

    def "unhappy test"
        when:
        def response = MockMvc.perform(get("/complicated").param("names", new ArrayList<>()))
            .andReturn()
            .getResponse();

        then:
        response.status == OK.value()


}

throws this:

No signature of method: org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder.param() is applicable for argument types: (java.lang.String, java.util.ArrayList) values: [names, []]. Possible solutions: param(java.lang.String, [Ljava.lang.String;), params(org.springframework.util.MultiValueMap), wait(), grep(), any(), putAt(java.lang.String, java.lang.Object)])
like image 888
Jay Avatar asked Jul 11 '17 20:07

Jay


People also ask

What is MockMvcBuilders standaloneSetup?

The MockMvcBuilders. standaloneSetup allows to register one or more controllers without the need to use the full WebApplicationContext .

What is MockHttpServletRequestBuilder?

public MockHttpServletRequestBuilder servletPath(String servletPath) Specify the portion of the requestURI that represents the path to which the Servlet is mapped. This is typically a portion of the requestURI after the context path.


2 Answers

ArrayList isn't supported but you can do the following

def "complicated test"
    when:
    def response = MockMvc.perform(get("/complicated").param("names", "bob", "margret"))
        .andReturn()
        .getResponse();

    then:
    response.status == OK.value()

def "another complicated test"
        when:
        def response = MockMvc.perform(get("/complicated").param("names", new String[]{"bob", "margret"}))
            .andReturn()
            .getResponse();

        then:
        response.status == OK.value()
like image 53
Sean Carroll Avatar answered Oct 13 '22 15:10

Sean Carroll


Use method params() instead of param() it supports multi value map, so you can have list of values for one key.

E.g.

    List<String> values = Arrays.asList("foo", "bar", "baz");
    MultiValueMap<String, String> params = new LinkedMultiValueMap<>()
    params.addAll("myKey", values);

    MockMvc.perform(get("/complicated")
            .params(params)
            .andReturn()
            .getResponse();
like image 36
ZZ 5 Avatar answered Oct 13 '22 13:10

ZZ 5