Skip to content

MockHandler

Troy Willmot edited this page Sep 25, 2016 · 1 revision

Mock Request Handler/Filter

Summary

The Mock Request handler/filter is used for automated (unit/integration) testing code that makes HTTP calls. It has two primary use cases;

  • Testing that the client makes correct requests.
  • Testing the client responds as expected to various responses.

Test responses can be configured per end point. The handler can be configured to return either a 'fixed' (hardcoded) response or a 'dynamic' response where a delegate or lambda function is executed at runtime to generate a response.

Each request made via the handler is stored in a read only collection exposed on the handler itself, so test code can examine and check the requests made by the code being tested.

By configuring the handler to return a specific response you can use regular test design to confirm the behaviour of code being tested without actually making network calls to a server.

Any request to an end point that not pre-configured with the handler will result in a 404 not found response. It is possible to configure a specific 'default' response in place of the 404 if required.

Any 'fixed' response registered with the handler will be cloned before being returned to the client. This avoids problems with content streams that can't be reused or needing their position reset.

Conditional Support

Conditional logic is NOT currently supported. Test responses are always returned, network calls are never made. However, dynamic requests can provide a lambda or delegate used to determine if that specific handler will handle a request. This is good for registered multiple handlers for different content types on the same end point etc.

Samples

Registering a Fixed Test Response

This sample shows how to register a 'fixed' response to a request. As no HTTP verb is specified on the AddFixedResponse call it will default to GET requests only. Because this is a 'fixed' response a copy of the same registered response is returned for every request.

Additionally this sample also shows how to check the last request made through the handler, which can be useful in test code to determine if the client is making the right requests.

// Configure response for the end point "http://www.mytestdomain.com/"
var requestUriString = "http://www.mytestdomain.com/";

var responseContentString = "Hello World!";
var responseMessage = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.OK)
{
    Content = new System.Net.Http.StringContent(responseContentString)
};

// Create a new mock handler and register the response we created for the end point.
var handler = new MockMessageHandler();
handler.AddFixedResponse(new Uri(requestUriString), responseMessage);

// Now make a rquest to our test endpoint, which will result in a cloned copy of the response we registered
// being returned.
var client = new System.Net.Http.HttpClient(handler);
var result = await client.GetAsync(requestUriString);

// Here we get a reference to the last request made via the handler and confirm
// that is was what we expected the client to have sent.
var lastRequest = handler.Requests.Last();
Assert.AreEqual("GET", lastRequest.Method.Method);
Assert.AreEqual(requestUriString, lastRequest.RequestUri.ToString());

Registering a Dynamic Response

This sample registers a 'dynamic' response to a 'greeting' end point. The request is a POST to the end point where the request content is a string containing a name.

The mock handler responds only to POST requests to the test end point, and returns a response that is 'Hello Name' where name is the content from the request (proving the response is dynamic and runtime generated).

var requestUriString = "http://www.mytestdomain.com/Greeting";

var handler = new MockMessageHandler();
handler.AddDynamicResponse(
    new MockResponseHandler()
    {
        // This decides if we will handle this specific request.
        CanHandleRequest = (request) =>
        {
            return request.RequestUri.ToString() == requestUriString
                && String.Compare(request.Method.Method, "POST", true) == 0; // Only handle POST requests to our end test endpoint
        },

        // This actually handles the request.
        HandleRequest = async (request) =>
        {
            // Read the text passed in the request and return it as part 
            // of our dynamic response.
            var name = await request.Content.ReadAsStringAsync().ConfigureAwait(false);
            var retVal = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.OK);
            retVal.Content = new System.Net.Http.StringContent("Hello " + name);

            return retVal;
        }
    }
);

var client = new System.Net.Http.HttpClient(handler);
var result = await client.PostAsync(requestUriString, new System.Net.Http.StringContent("Yort"));

Registering a Default Response

This sample shows how to register a custom response for requests where no other response is registered. Normally such requests would result in a 404 Not Found, but here the custom response is used. The custom response returned in this sample is a redirect to an HTML page called 'ohnoes.html'.

// This is the end point we'll GET to, but we won't register
// it with the handler, so it will be unhandled and result in
// the default response.
var requestUriString = "http://www.mytestdomain.com/";

// This is the location we're going to send back as a redirect to
// whenever any unhandled request is received.
var notFoundResponseUri = new Uri("http://www.mytestdomain.com/ohnoes.html");

// Here we create the handler and set the default response.
var handler = new MockMessageHandler();
handler.DefaultResponse = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.Redirect);
handler.DefaultResponse.Headers.Location = notFoundResponseUri;

// Now create a client and make the call, which will result in a copy of the 
// default response being returned.
var client = new System.Net.Http.HttpClient(handler);
var result = await client.GetAsync(requestUriString);

Clone this wiki locally