Mocking HTTP responses in Android using Robolectric

One of the nice features of Robolectric, is its ability to intercept HTTP requests and provide a way to return the HTTP responses you want. It is very useful, if you want to test code that reacts on certain HTTP requests. To accomplish this, Robolectric provides a fake HTTP layer, which you can configure with different complexity levels depending on your needs.

  • One response for all: Robolectric.setDefaultHttpResponse
    Using this static method, you can set a HTTP response that is returned by the fake HTTP layer when there is no other response rule matching. If you only set an HTTP response with this method, all HTTP requests made will receive the given HTTP response as return value.
    E.g. if you always want to return just a success code, you could use the following line of code:

    Robolectric.setDefaultHttpResponse(200, "response body");
    

    or you always want to fail:

    Robolectric.setDefaultHttpResponse(400, null);
    
  • Using defined order of HTTP responses: Robolectric.addPendingHTTPResponse
    Using these static method, you can just put HTTP responses in a queue, which will then be returned by Robolectric one after the other for consecutive HTTP requests.

    Say, the first HTTP request should return a status code of 400 and the second one a status code of 200:

    Robolectric.addPendingHttpResponse(400, null);
    Robolectric.addPendingHttpResponse(200, "some content");
    

    To make sure a failing test does not leave some responses in the queue, you should always call Robolectric.clearPendingHTTPResponses after each test.

  • Complex response rules: Robolectric.addHTTPResponseRule
    In some cases it can be useful to setup the fake HTTP layer to return HTTP responses based on hostaddress, the path on the server, the HTTP method, etc. E.g. if you want to provide a 200 response for the uri http://www.myserver.com/successfullcall and a 400 response for the uri http://www.myserver.com/failedcall you can use the following code:

    ProtocolVersion httpProtocolVersion = new ProtocolVersion("HTTP", 1, 1);
    HttpResponse successResponse = 
            new BasicHttpResponse(httpProtocolVersion, 200, "OK");
    Robolectric.addHttpResponseRule("http://www.myserver.com/successfullcall", successResponse);
    
    HttpResponse failedResponse =
            new BasicHttpResponse(httpProtocolVersion, 400, "Bad Request");
    Robolectric.addHttpResponseRule("http://www.myserver.com/failedcall", failedResponse);
    

    Of course, you can also provide some content with your responses by adding an entity to the response object:

    successResponse.setEntity(
            new StringEntity("the content to return"));
    
  • Dynamic Responses
    Instead of adding static responses to some pre-defined rules, you can also create an object that inherits from ResponseRule and where you can create new HTTP response on every request.
    As an example we want to return the number of the request as content each time our rule matches:

    class CountingResponseRule implements ResponseRule {
    
        private int mCounter = 0;
    
        @Override
        public HttpResponse getResponse() throws HttpException, IOException {
            HttpResponse response= new BasicHttpResponse(
                       new ProtocolVersion("HTTP", 1, 1), 200, "OK");
            response.setEntity(new StringEntity(Integer.toString(mCounter));
            mCounter++;
    
            return response;
        }
    
        @Override
        public boolean matches(HttpRequest request) {
            String uri = request.getRequestLine().getUri();
            if (uri.equals("http://www.myserver.com/counter")) {
                return true;
            }
    
            return false;
        }
    }
    

    Then add this rule using

    Robolectric.getFakeHttpLayer().addResponseRule(
            new CountingResponseRule()));
    

Conclusion
Robolectric provides a powerful way to return different HTTP responses to HTTP requests in your code and test how your code reacts on these responses. It is easy to create test cases which verify that your code will behave correctly even if the server reacts with weird responses.


My other articles about Robolectric might also be interesting for you.