.NET:HttpClient用我的接口IHttpClient模拟它,但有一个内部对象是NULL,它是密封的
本文关键字:内部对象 有一个 NULL 密封 HttpClient 接口 我的 IHttpClient 模拟 NET | 更新日期: 2023-09-27 18:32:39
我想知道是否有人可以提供帮助。我已经创建了自己的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; }
提前致谢
只需注入具体的 HttpClient 并模拟底层的 HttpMessageHandler...
http://geekswithblogs.net/abhi/archive/2013/11/20/unit-tests-for-httpclient-using-httpmessagehandler.aspx
你可以对使用 HttpClient 的类进行单元测试,方法是提供HttpClient 一个模拟的 HttpMessageHandler。这样,您可以捕获请求并防止它实际通过电线。
下面是使用最小起订量的示例。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); }
HttpRequestHeaders
只有内部构造函数。但是你可以通过创建HttpRequestMesssage
对象来做到这一点:
var message = new HttpRequestMessage();
.Setup(x => x.DefaultRequestHeaders).Returns(message.Headers);
Returns
方法调用的语法似乎不正确。HttpRequestHeaders
是一个密封类这一事实不应与是否可以从存根方法调用返回它的实例有任何关系。尝试将该调用更改为 Returns(new HttpRequestHeaders());
或 Returns(() => new HttpRequestHeaders());
。
如果这不起作用(或者HttpRequestHeaders
的具体实现在某种程度上不适合您的需求),您可能需要尝试一个可以模拟密封类的框架,可能是 Moles 或 JustMock。