3

While doing some searches on SO I came across this piece of code to extract the "appUrl" from a URL:

public static String getAppUrl(HttpServletRequest request)
{
     String requestURL = request.getRequestURL().toString();
      String servletPath = request.getServletPath();
      return requestURL.substring(0, requestURL.indexOf(servletPath));
}

My question is how does one unit test something like this? The key problem is how to create an instance of HttpServletRequest for unit testing?

Fwiw I tried some googling and most of the responses center around mocking the class. But if I mock the class so that getRequestURL returns what I want it to return (taking an example since mocking essentially overrides some methods to return canned values), then I am not really testing the code at that point. I also tried the httpunit library but that also does not help.

Community
  • 1
  • 1
morpheus
  • 18,676
  • 24
  • 96
  • 159
  • You're mocking the dependencies, not the System Under Test. You're not testing the getRequestURL here, because it's not in the scope – Alexandru Marculescu Sep 07 '16 at 06:27
  • Possible duplicate of [Unit testing a Java Servlet](http://stackoverflow.com/questions/90907/unit-testing-a-java-servlet) – worpet Sep 07 '16 at 16:37
  • 1
    You could try using `org.springframework.mock.web.MockHttpServletRequest` within `spring-test` maven dependency. It worked for what I needed. – Mike Croteau Aug 18 '20 at 12:46

1 Answers1

11

I use mockito and here is the block of code in the test method I use to mock it up:

public class TestLogin {
@Test
public void testGetMethod() throws IOException {
    // Mock up HttpSession and insert it into mocked up HttpServletRequest
    HttpSession session = mock(HttpSession.class);
    given(session.getId()).willReturn("sessionid");

    // Mock up HttpServletRequest
    HttpServletRequest request = mock(HttpServletRequest.class);
    given(request.getSession()).willReturn(session);
    given(request.getSession(true)).willReturn(session);
    HashMap<String,String[]> params = new HashMap<>();
    given(request.getParameterMap()).willReturn(params);

    // Mock up HttpServletResponse
    HttpServletResponse response = mock(HttpServletResponse.class);
    PrintWriter writer = mock(PrintWriter.class);
    given(response.getWriter()).willReturn(writer);

    .....

Hope that helps, I use this to test methods that require servlet objects to work.

AlexC
  • 1,395
  • 14
  • 26
  • I don't think this will work because what will the object return when getRequestUrl and getServletUrl are called? And if I mock those methods then I will not really be testing their actual behavior. – morpheus Sep 07 '16 at 04:08
  • Why would you want to test those, do you not trust that the app server, in that it may misbehave? If so you may want to consider embedding something like jetty and using it to run your tests, but that will make your tests very complicated. Unit tests should be testing your code, if you don't trust the framework, then build integration tests with something like httpunit that run after the server is deployed and running. – AlexC Sep 07 '16 at 04:13
  • A consideration, how do you call the method `getAppUrl()` in the test? I mean, how do you instantiate the parameter of type `HttpServletResponse`? Because in the test you have to call the method, but I didn't get how to instantiate the object. – A. Wolf Dec 12 '20 at 18:35