ASP.NET Core单元测试中如何Mock HttpClient.GetStringAsync()的示例分析,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。
皋兰网站建设公司创新互联,皋兰网站设计制作,有大型网站制作公司丰富经验。已为皋兰近1000家提供企业网站建设服务。企业网站搭建\成都外贸网站制作要多少钱,请找那个售后服务好的皋兰做网站的公司定做!
在 ASP.NET Core 单元测试中模拟HttpClient.GetStringAsync() 的技巧。
下面这个代码
var html = await _httpClient.GetStringAsync(sourceUrl);
如果按正常思路像这样去 Mock HttpClient.GetStringAsync()
var httpClientMock = new Mock(); httpClientMock .Setup(p => p.GetStringAsync(It.IsAny ())) .Returns(Task.FromResult("..."));
Exception
System.NotSupportedException : Unsupported expression: p => p.GetStringAsync(It.IsAny())Non-overridable members (here: HttpClient.GetStringAsync) may not be used in setup / verification expressions.
我们需要 Mock HttpClient 底层使用的 HttpMessageHandler 而不是 HttpClient
var handlerMock = new Mock(); var magicHttpClient = new HttpClient(handlerMock.Object);
然后我花了 9.96 分钟研究了 HttpClient.GetStringAsync() 的源代码,发现它最终调用的是 SendAsync() 方法
private async TaskGetStringAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken) { // ... response = await base.SendAsync(request, cts.Token).ConfigureAwait(false); // ... }
源代码位置:https://source.dot.net/#System.Net.Http/System/Net/Http/HttpClient.cs,170
因此,我们的 Mock Setup 如下:
handlerMock .Protected() .Setup>( "SendAsync", ItExpr.IsAny (), ItExpr.IsAny () ) .ReturnsAsync(new HttpResponseMessage { StatusCode = HttpStatusCode.OK, Content = new StringContent("the string you want to return") }) .Verifiable();
现在 Mock 就能运行成功了!
最后附上完整的 UT 代码供参考:
using System.Net; using System.Net.Http; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Moq; using Moq.Protected; using NUnit.Framework; namespace Moonglade.Pingback.Tests { [TestFixture] public class PingSourceInspectorTests { private MockRepository _mockRepository; private Mock> _mockLogger; private Mock _handlerMock; private HttpClient _magicHttpClient; [SetUp] public void SetUp() { _mockRepository = new(MockBehavior.Default); _mockLogger = _mockRepository.Create >(); _handlerMock = _mockRepository.Create (); } private PingSourceInspector CreatePingSourceInspector() { _magicHttpClient = new(_handlerMock.Object); return new(_mockLogger.Object, _magicHttpClient); } [Test] public async Task ExamineSourceAsync_StateUnderTest_ExpectedBehavior() { string sourceUrl = "https://996.icu/work-996-sick-icu"; string targetUrl = "https://greenhat.today/programmers-special-gift"; _handlerMock .Protected() .Setup >( "SendAsync", ItExpr.IsAny (), ItExpr.IsAny () ) .ReturnsAsync(new HttpResponseMessage { StatusCode = HttpStatusCode.OK, Content = new StringContent($"" + $"" + $" Programmer's Gift " + $"" + $"Work 996 and have a green hat!" + $"") }) .Verifiable(); var pingSourceInspector = CreatePingSourceInspector(); var result = await pingSourceInspector.ExamineSourceAsync(sourceUrl, targetUrl); Assert.IsFalse(result.ContainsHtml); Assert.IsTrue(result.SourceHasLink); Assert.AreEqual("Programmer's Gift", result.Title); Assert.AreEqual(targetUrl, result.TargetUrl); Assert.AreEqual(sourceUrl, result.SourceUrl); } } }
看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注创新互联行业资讯频道,感谢您对创新互联的支持。