Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET: HttpClient mocking it with my Interface IHttpClient, but there is an internal object that is NULL and it is sealed

I wonder if anyone can help. I have created my own IHttpClient so I am able to mock HttpClient using moq. Works pretty well but there is an internal object called DetaultRequestHeaders which has a property called Authorization.

I am setting this in my constructor or my class that accepts in an injected IHttpClient, of course at runtime everything works as expected. But using Unit Tests I get an error saying

    Object reference not set to instance....

This is due to the fact that the DefaultRequestHeaders is null.

Now after inverstigating this further it appears that it is of type

    HttpRequestHeaders

but its a sealed class so i can't even do this

    .Setup(x => x.DefaultRequestHeaders).Returns(return new HttpRequestHeaders())

Does anyone have any experience in this ?

This is the interface definition

    HttpRequestHeaders DefaultRequestHeaders { get; }

Thanks in advance

like image 245
Martin Avatar asked Sep 23 '13 15:09

Martin


1 Answers

Just inject the concrete HttpClient and mock the underlying HttpMessageHandler...

http://geekswithblogs.net/abhi/archive/2013/11/20/unit-tests-for-httpclient-using-httpmessagehandler.aspx

You can unit test a class that uses HttpClient by giving that HttpClient a mock HttpMessageHandler. This way, you can capture the request and prevent it from actually going over the wire.

Here is an example using Moq. HttpClient depends on HttpMessageHandler’s SendAsync() method, so give SendAsync() a stub implementation and use Moq’s Callback() to capture arguments.

var handler = new Mock<HttpMessageHandler>();

handler.Protected()

    .Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>())

    .Returns(Task<HttpResponseMessage>.Factory.StartNew(() =>

    {

        return new HttpResponseMessage(HttpStatusCode.OK);

    }))

    .Callback<HttpRequestMessage, CancellationToken>((r, c) =>

    {

        Assert.AreEqual(HttpMethod.Get, r.Method);

    });

 

using (var client = new HttpClient(handler.Object))

{

    var request = new HttpRequestMessage(HttpMethod.Get, "http://www.google.com");

    var response = client.SendAsync(request).Result;

    Console.WriteLine(response.StatusCode);

}
like image 170
JoshSchlesinger Avatar answered Sep 20 '22 04:09

JoshSchlesinger