2

I am going to unit test a Spring MVC controller (or whole site if possible).

I want to pass a URL (as a string), e.g. "/metrics/filter?a1=1&a2=2&a3=abcdefg&wrongParam=WRONG" and check what controller will return.

Is there an easy way to do it?

Example:

 @RequestMapping(value = {"/filter"}, method = RequestMethod.GET)
    @ResponseBody
    public List<MetricType> getMetricTypes(
             @RequestParam(value = "subject", required = false) Long subjectId
            ,@RequestParam(value = "area", required = false) Long areaId
            ,@RequestParam(value = "onlyImmediateChildren", required = false) Boolean onlyImmediateChildren

            ,@RequestParam(value = "componentGroup", required = false) Long componentGroupId

            ,@RequestParam(value = "hasComponentGroups", required = false) Boolean hasComponentGroups
                                            ) throws Exception
    {
          //some code
    }

Many thanks

Maxim

UPDATED

  • I only use GET, not post
  • I do not use model objects (see example above)
  • My system is a web service which has a lot of "/someEntity/filter?a1=123&a2=1234&a3=etc" method with various combinations of parameters. I am not sure it is practical to use model objects in this case.

3 Answers 3

3
@RunWith( SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:WebRoot/WEB-INF/path/to/your-context.xml") 
public class YourControllerTest {

    private MockHttpServletRequest request;
    private MockHttpServletResponse response;
    private AnnotationMethodHandlerAdapter adapter;


@Before
public void setUp(){
    this.request = new MockHttpServletRequest();
    this.response = new MockHttpServletResponse();
    this.adapter = new AnnotationMethodHandlerAdapter();
}


    @Test
    public void getMetricTypes() throws Exception{



        request.setRequestURI("/filter");
        request.setMethod("GET");
        request.setParameter("subject", "subject");
        request.setParameter("area", "area");    
        request.setParameter("onlyImmediateChildren", "onlyImmediateChildren");    
        request.setParameter("componentGroup", "componentGroup");    
        request.setParameter("hasComponentGroups", "hasComponentGroups");    

        ModelAndView mav = adapter.handle(request, response, yourController);
        Assert.assertEquals(200, response.getStatus());
        //Assert what you want
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

It looks interesting. Sorry for being novice in Spring MVC, but how to get/create request and response objects? I pasted your code to IDE and it does not compile.
I have initialised request and response as follows: "MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletResponse response = new MockHttpServletResponse(); ". Now I cannot run the test - it fails with NullPointerException.
0

A new and easier way for testing Spring MVC controllers is spring-test-mvc.

Comments

0

Most people recommend not integration testing the request mappings - you can unit test your controllers pojo methods: ie without any spring bindings. Whats the point of testing if Spring is working is the argument put forward.

So in your unit test call the controller method normally passing in an implementation of model as parameter (extendedmodelmap(?). The test code can then check what gets added to model, and also the return values.

If you really want to integration test spring-mvc this article is good.

3 Comments

"Most people recommend not integration testing the request mappings " - I tried unit tests and they seems to be too heavyweight for my methods. I'd like to try the integration test approach with string URLs (including query string).
@MaximEliseev I used to think that, then I went over to the unit test way as I laid out - its much simpler and more lightweight - you don't need to load up an app context. I thoroughly recommend it. Its why spring was created in the first place (well one of the major benefits of it - easier testing, less binding).
Thank you for comment. I tried to write unit tests for these controllers and it is not very quick. I am going to have a lot of similar tests, checking valid parameter combinations. I'd like to specify my tests in a CSV file with a URL (e.g. "/metricTypes/filter?area=123&wrongParam=Bad") and some boolean columns, e.g. IsException Expected), and then to run the test from these CSV files using the generic code. It would make adding new test a 10-second job.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.