Unit Testing

Unit testing code that uses RestClient is trivial - use the UnitTestHandler to fake responses without hitting the network, and the Verify method from DalSoft.RestClient.Testing to assert the results fluently.

[Fact]
public async Task GetUser_ProvidingAValidUserId_ReturnsExpectedUser()
{
    var client = new RestClient("http://test.com", new Config()
        .UseUnitTestHandler(request => new HttpResponseMessage
        {
            Content = new StringContent("{ \"id\": 1, \"username\": \"Bret\" }")
        }));

    await client.Resource("users/1").Get()
        .Verify<HttpResponseMessage>(response => response.IsSuccessStatusCode)
        .Verify<User>(user => user.Username == "Bret");
}

The UnitTestHandler can fake/mock pretty much anything in RestClient - including asserting anything about the request. See UnitTestHandler for detailed info on the handler.

Mocking a RestClient dependency

The simplest mock is no mock at all - because RestClient’s behaviour comes from the pipeline, a real RestClient configured with the UnitTestHandler is the fake. How you hand it to the code under test depends on what that code takes:

A typed client or anything taking IRestClient - pass it a RestClient with faked responses:

var gitHubClient = new GitHubClient(new RestClient("http://test.com", new Config()
    .UseUnitTestHandler(request => new HttpResponseMessage
    {
        Content = new StringContent("[{ \"name\": \"DalSoft.RestClient\" }]")
    })));

var repositories = await gitHubClient.GetRepositories("dalsoft");

Assert.Equal("DalSoft.RestClient", repositories.Single().Name);

Code taking IRestClientFactory (see IHttpClientFactory) - provide a factory returning that RestClient, handy for unit tests and for overriding services in e2e tests:

public class MockRestClientFactory : IRestClientFactory
{
    public RestClient CreateClient()
    {
        return new RestClient
        (
            "http://NotUsedAsMockResponseReturned",
            new Config()
                .UseUnitTestHandler(request => new HttpResponseMessage
                {
                    Content = new StringContent("[{ \"name\": \"Hello World\" }]")
                })
        );
    }

    public RestClient CreateClient(string name)
    {
        return CreateClient();
    }
}

Code taking IHttpClientWrapper - if you’d rather mock at the transport level, RestClient has a constructor taking IHttpClientWrapper (its one method Send returns the HttpResponseMessage). You get the same result as the UnitTestHandler with more setup, so prefer the handler unless you have a reason not to:

var mockHttpClient = new Mock<IHttpClientWrapper>();

mockHttpClient
    .Setup(_ => _.Send(HttpMethod.Get, It.IsAny<Uri>(), It.IsAny<IDictionary<string, string>>(), It.IsAny<object>()))
    .Returns(Task.FromResult(new HttpResponseMessage { RequestMessage = new HttpRequestMessage() }));

dynamic client = new RestClient(mockHttpClient.Object, "http://test.test");

Updated: