How to Mock HttpServletRequest – 如何模拟HttpServletRequest

最后修改: 2022年 6月 4日

1. Overview


In this quick tutorial, we’ll look at a few ways to mock a HttpServletRequest object.


First, we’ll start with a fully functional mock type – MockHttpServletRequest from the Spring Test library. Then, we’ll see how to test using two popular mocking libraries – Mockito and JMockit. Finally, we’ll see how to test using an anonymous subclass.


2. Testing HttpServletRequest


Testing Servlets can be tricky when we want to mock the client request information such as HttpServletRequest. In addition, this interface defines various methods, and there are different approaches available to mock these methods.


Let’s look at the target UserServlet class that we want to test:


public class UserServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String firstName = request.getParameter("firstName");
        String lastName = request.getParameter("lastName");

        response.getWriter().append("Full Name: " + firstName + " " + lastName);

To unit test the doGet() method, we’ll need to mock both request and response parameters to simulate the actual runtime behavior.


3. Using MockHttpServletRequest from Spring


Spring-Test library provides a fully functional class MockHttpServletRequest that implements the HttpServletRequest interface.


Though this library is primarily aimed at testing Spring applications, we can use its MockHttpServletRequest class without implementing any Spring-specific functionality. In other words, even if the application doesn’t use Spring we can still have this dependency just to mock HttpServletRequest objects.


Let’s add this dependency to pom.xml:

让我们把这个依赖性添加到 pom.xml 中。


Now, let’s see how we can use this class to test the UserServlet:


void givenHttpServletRequest_whenUsingMockHttpServletRequest_thenReturnsParameterValues() throws IOException {
    MockHttpServletRequest request = new MockHttpServletRequest();
    request.setParameter("firstName", "Spring");
    request.setParameter("lastName", "Test");
    MockHttpServletResponse response = new MockHttpServletResponse();

    servlet.doGet(request, response);

    assertThat(response.getContentAsString()).isEqualTo("Full Name: Spring Test");

Here, we can notice that there is no actual mocking involved. We have used the fully functional request and response objects and tested the target class with just a few lines of code. As a result, the test code is clean, readable, and maintainable. 


4. Using Mocking Frameworks


Alternatively, mocking frameworks provide a clean and simple API to test mock objects that mimic the run time behavior of the original object.


Some of their strong points are their expressibility and the out-of-the-box ability to mock static and private methods. Further, we can avoid most of the boilerplate code needed for mocking (compared to custom implementations) and instead focus on the tests.


4.1. Using Mockito


Mockito is a popular open-source test automation framework that internally uses Java Reflection API to create mock objects.

Mockito是一个流行的开源测试自动化框架,其内部使用Java Reflection API来创建模拟对象。

Let’s get started by adding the mockito-core dependency to our pom.xml:

让我们开始吧,将mockito-core 依赖性添加到我们的pom.xml


Next, let’s see how we can mock the getParameter() method from the HttpServletRequest object:


void givenHttpServletRequest_whenMockedWithMockito_thenReturnsParameterValues() throws IOException {
    // mock HttpServletRequest & HttpServletResponse
    HttpServletRequest request = mock(HttpServletRequest.class);
    HttpServletResponse response = mock(HttpServletResponse.class);

    // mock the returned value of request.getParameterMap()
    when(response.getWriter()).thenReturn(new PrintWriter(writer));

    servlet.doGet(request, response);

    assertThat(writer.toString()).isEqualTo("Full Name: Mockito Test");

4.2. Using JMockit


JMockit is a mocking API that provides useful recording and verification syntax (we can use it for both JUnit and TestNG ones). It is an out-of-container integration testing library for Java EE and Spring-based apps. Let’s see how we can mock HttpServletRequest using JMockit.

JMockit是一个嘲弄API,它提供了有用的记录和验证语法(我们可以将其用于JUnitTestNG的)。它是一个用于Java EE和基于Spring的应用程序的容器外集成测试库。让我们看看我们如何使用JMockit来模拟HttpServletRequest

First, we’ll add the jmockit dependency to our project:

首先,我们将把jmockit 依赖添加到我们的项目中。


Next, let’s proceed with the mock implementation in the test class:


HttpServletRequest mockRequest;
HttpServletResponse mockResponse;

void givenHttpServletRequest_whenMockedWithJMockit_thenReturnsParameterValues() throws IOException {
    new Expectations() {{
        mockRequest.getParameter("firstName"); result = "JMockit";
        mockRequest.getParameter("lastName"); result = "Test";
        mockResponse.getWriter(); result = new PrintWriter(writer);

    servlet.doGet(mockRequest, mockResponse);

    assertThat(writer.toString()).isEqualTo("Full Name: JMockit Test");

As we can see above, with just a few lines of setup, we have successfully tested the target class with a mock HttpServletRequest object.


Thus, mocking frameworks can save us a lot of legwork and make unit tests a lot faster to write. On the contrary, to use mock objects, one needs to understand the mock API, and usually, it requires a separate framework.

因此,模拟框架可以为我们节省大量的腿部工作,使单元测试的编写速度大大加快。相反,要使用mock对象,需要了解mock API,而且通常需要一个单独的框架。

5. Using Anonymous Subclass


Some projects may have dependency constraints or prefer direct control over their own test class implementations. Specifically, this might be useful in the case of a larger servlet code base where the reusability of custom implementations is important. In these cases, anonymous classes come in handy.


Anonymous classes are inner classes with no name. Moreover, they are quick to implement and provide direct control over the actual object. This approach can be considered if we don’t want to include an additional dependency for tests.


Now, let’s create an anonymous subclass that implements the HttpServletRequest interface and use it to test the doGet() method:


public static HttpServletRequest getRequest(Map<String, String[]> params) {
    return new HttpServletRequest() {
        public Map<String, String[]> getParameterMap() {
            return params;

        public String getParameter(String name) {
            String[] values = params.get(name);
            if (values == null || values.length == 0) {
                return null;
            return values[0];

        // More methods to implement

Next, let’s pass this request to the class under test:


void givenHttpServletRequest_whenUsingAnonymousClass_thenReturnsParameterValues() throws IOException {
    final Map<String, String[]> params = new HashMap<>();
    params.put("firstName", new String[] { "Anonymous Class" });
    params.put("lastName", new String[] { "Test" });

    servlet.doGet(getRequest(params), getResponse(writer));

    assertThat(writer.toString()).isEqualTo("Full Name: Anonymous Class Test");

The drawback of this solution is the need to create an anonymous class with dummy implementations for all the abstract methods. In addition, there are chances that nested objects like HttpSession may require specific implementations.


6. Conclusion


In this article, we discussed a few options for mocking the HttpServletRequest object when writing unit tests for servlets. Besides using the mocking frameworks, we saw that testing with the MockHttpServletRequest class seems to be more clean and efficient than custom implementations.


As always, the code for these examples is available over on GitHub.