如何在单元测试中验证Flurl Http中的请求正文内容?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在单元测试中验证Flurl Http中的请求正文内容?相关的知识,希望对你有一定的参考价值。
我正在使用Flurl Http发出http请求。在单元测试中,我试图验证预期的内容是否已传递给发件人。我正在尝试:
httpTest.ShouldHaveCalled(url)
.WithVerb(HttpMethod.Post)
.WithContentType(contentType)
.With(w => w.Request.Content.ReadAsStringAsync().Result == content)
.Times(1);
但是,此操作失败,并显示System.ObjectDisposedException Cannot access a disposed object. Object name: 'System.Net.Http.StringContent'.
看起来Flurl在测试中完成验证之前正在处理请求正文内容。如何捕获请求正文以进行验证?
编辑(完全可复制的示例):
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Autofac.Extras.Moq;
using Flurl.Http;
using Flurl.Http.Testing;
using Xunit;
namespace XUnitTestProject1
{
public class MyClassTest : IDisposable
{
private readonly AutoMock container;
private readonly HttpTest client;
public MyClassTest()
{
this.container = AutoMock.GetLoose();
this.client = new HttpTest();
}
[Fact]
public async Task SendAsync_ValidateRequestBody()
{
const string url = "http://www.example.com";
const string content = "Hello, world";
var sut = this.container.Create<MyClass>();
await sut.SendAsync(url, content);
this.client.ShouldHaveCalled(url)
.With(w =>
{
var x = w.RequestBody;
return w.RequestBody == content;
});
}
public void Dispose()
{
this.container?.Dispose();
this.client?.Dispose();
}
}
public class MyClass
{
public virtual async Task SendAsync(string url, string content)
{
await url.PostAsync(new StringContent(content, Encoding.UTF8, "text/plain"));
}
}
}
答案
它已经被捕获,您只需以不同的方式访问它。
在您的示例中,w.Request
是Flurl公开的HttpRequestMessage堆栈中的“原始” HttpClient
,因此您可以根据需要进行深入研究。 HttpRequestMessage.Content
是一次只读,仅转发的流,在您访问它时已被读取和处置。
[幸运的是,Flurl已将请求主体捕获为字符串,并通过其HttpCall.RequestBody
属性公开了它。所以就这样做:
.With(w => w.RequestBody == content)
以上是关于如何在单元测试中验证Flurl Http中的请求正文内容?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Alamofire 为 http 请求编写单元测试?
ASP.Net Core 2.1 和 IHttpClientFactory 中的 Flurl 客户端生命周期