Skip to content
Pure Krome edited this page Dec 22, 2016 · 8 revisions

Single endpoint

What: faking a single request endpoint

Why: unit testing a service that makes a request to one endpoint.

How: Create a fake response for the single endpoint.

public class MyService : IMyService
{
    private readonly FakeHttpMessageHandler _messageHandler;

    public MyService(FakeHttpMessageHandler messageHandler = null)
    {
        _messageHandler = messageHandler;
    }

    public async Task<Foo> GetSomeDataAsync()
    {
        HttpResponseMessage message;
        string content;
        using (var httpClient = _messageHandler == null
           ? new System.Net.Http.HttpClient()
           : System.Net.Http.HttpClient(_messageHander))
        {
            message = await httpClient.GetAsync("http://www.something.com/some/website");
            content = await message.Content.ReadAsStringAsync();
        }
        
        if (message.StatusCode != HttpStatusCode.OK)
        { 
            // TODO: handle this ru-roh-error.
        }
        
        // Assumption: content is in a json format.
        var foo = JsonConvert.DeserializeObject<Foo>(content);
        
        return foo;
    }
}

// ... and some unit tests ...

// Most simplest example, least amount of code or customization.
[Fact]
public async Task GivenAValidHttpRequest_GetSomeDataAsync_ReturnsAFoo()
{
    // Arrange.
    const string requestUrl = "http://www.something.com/some/website";  
    const string responseData = "{ \"Id\":69, \"Name\":\"Jane\" }";
    
    // 1. Fake response.  
    var messageResponse = FakeHttpMessageHandler.GetStringHttpResponseMessage(responseData);  

    // 2. Fake handler that says: for this Url return this (fake) response.  
    var options = new HttpMessageOptions
    {
        HttpResponseMessage = messageResponse,
        RequestUri = requestUrl
    };
    var messageHandler = new FakeHttpMessageHandler(options);
    
    var myService = new MyService(messageHandler);

    // Act.
    // NOTE: network traffic will not leave your computer because you've faked the response, above.
    var result = myService.GetSomeDataAsync();
    
    // Assert.
    result.Id.ShouldBe(69);
}

// More complex example where we have manually specified the HttpMethod, Request Url and response.
[Fact]
public async Task GivenAValidHttpRequestWithSomeCustomization_GetSomeDataAsync_ReturnsAFoo()
{
    // Arrange.
    const string requestUrl = "http://www.something.com/some/website";  
    const string responseData = "{ \"Id\":69, \"Name\":\"Jane\" }";
    
    // 1. Fake response.  
    var options = new HttpMessageOptions
                  {
                      HttpMethod = HttpMethod.Get,
                      RequestUri = requestUrl,
                      HttpResponseMessage = responseData 
                  };
    var messageHandler = new FakeHttpMessageHandler(options);
    
    var myService = new MyService(messageHandler);

    // Act.
    // NOTE: network traffic will not leave your computer because you've faked the response, above.
    var result = myService.GetSomeDataAsync();
    
    // Assert.
    result.Id.ShouldBe(69);
}