如何在单元测试中验证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中的请求正文内容?的主要内容,如果未能解决你的问题,请参考以下文章

Flurl Http 用法

如何使用 Alamofire 为 http 请求编写单元测试?

ASP.Net Core 2.1 和 IHttpClientFactory 中的 Flurl 客户端生命周期

Laravel 5.5 中 PHP 单元测试中的类验证器错误

python如何开展单元测试?

如何对正在进行的 RXJS 请求的取消进行单元测试