单元测试 | 如何Mock IHttpClientFactory
Posted dotNET跨平台
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单元测试 | 如何Mock IHttpClientFactory相关的知识,希望对你有一定的参考价值。
前言
编写单元测试时,常常需要使用Mock框架(例如Moq)生成测试类的依赖接口的"模拟"实现,并验证接口是否按预期使用:
_mediatorMock = new Mock<IMediator>();
_mediatorMock.Setup(x => x.Send(It.IsAny<IdentifiedCommand<CancelOrderCommand, bool>>(), default(CancellationToken)))
.Returns(Task.FromResult(true));
但是,对于IHttpClientFactory就不仅仅是Mock<IHttpClientFactory>这么简单了!
问题
因为,在实现代码中,我们并不是直接使用IHttpClientFactory对象,而是IHttpClientFactory对象使用CreateClient方法生成的HttpClient实例,而且我们也不希望真正的执行HTTP调用。
因此,我们需要Mock这种依赖性,并处理HttpClient实例的调用返回。
实现
IHttpClientFactory的Mock代码非常简单:
var httpClient = new HttpClient(handlerMock.Object)
BaseAddress = new Uri("https://www.baidu.com/")
;
var mockHttpClientFactory = new Mock<IHttpClientFactory>();
mockHttpClientFactory.Setup(x => x.CreateClient("Baidu")).Returns(httpClient);
关键点在于,HttpClient构造函数传入的Mock对象handlerMock,它是用于实现发送请求的HTTP处理程序:
HttpResponseMessage result = new HttpResponseMessage();
handlerMock
.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
It.IsAny<HttpRequestMessage>(),
It.IsAny<CancellationToken>()
)
.ReturnsAsync(result)
由于HttpMessageHandler的SendAsync方法可访问性级别是protected,因此需要使用.Protected()进行设置:
我们可以修改It.IsAny(),以匹配实际的请求。比如:
It.Is<HttpRequestMessage>(req =>
req.RequestUri.Query.Contains("My%20IO")
)
现在,我们就可以在单元测试中正常使用IHttpClientFactory了
service = new DemoService(mockHttpClientFactory.Object);
结论
在本文中,我们实现了Mock IHttpClientFactory。
如果你觉得这篇文章对你有所启发,请关注我的个人公众号”My IO“
以上是关于单元测试 | 如何Mock IHttpClientFactory的主要内容,如果未能解决你的问题,请参考以下文章