13

我想知道是否有人可以提供帮助。我创建了自己的 IHttpClient,因此我可以使用 moq 模拟 HttpClient。工作得很好,但是有一个名为 DetaultRequestHeaders 的内部对象,它有一个名为 Authorization 的属性。

我在我的构造函数或接受注入的 IHttpClient 的类中设置它,当然在运行时一切都按预期工作。但是使用单元测试我得到一个错误说

    Object reference not set to instance....

这是因为 DefaultRequestHeaders 为空。

现在在进一步调查之后,它似乎是类型

    HttpRequestHeaders

但它是一个密封的类,所以我什至不能这样做

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

有没有人有这方面的经验?

这是接口定义

    HttpRequestHeaders DefaultRequestHeaders { get; }

提前致谢

4

3 回答 3

16

只需注入具体的 HttpClient 并模拟底层的 HttpMessageHandler ...

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

您可以通过为 HttpClient 提供一个模拟 HttpMessageHandler 来对使用 HttpClient 的类进行单元测试。这样,您可以捕获请求并防止它实际通过网络。

这是一个使用 Moq 的示例。HttpClient 依赖于 HttpMessageHandler 的 SendAsync() 方法,因此给 SendAsync() 一个存根实现并使用 Moq 的 Callback() 来捕获参数。

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);

}
于 2014-01-15T13:59:30.417 回答
3

HttpRequestHeaders只有内部构造函数。但是您可以通过创建HttpRequestMesssage对象来做到这一点:

var message = new HttpRequestMessage();
.Setup(x => x.DefaultRequestHeaders).Returns(message.Headers);
于 2017-12-29T08:15:03.053 回答
-2

Returns您在方法调用上的语法似乎不正确。密封类的事实与HttpRequestHeaders您是否可以从存根方法调用返回它的实例没有任何关系。尝试将该调用更改为Returns(new HttpRequestHeaders());or Returns(() => new HttpRequestHeaders());

如果这不起作用(或者具体实现在HttpRequestHeaders某种程度上不适合您的需求),您可能需要尝试一个可以模拟密封类的框架,也许是 Moles 或 JustMock。

于 2013-09-24T02:40:01.820 回答