在测试中读取请求 HttpContent 时出现 ObjectDisposedException

ObjectDisposedException when reading requests HttpContent in test

我正在使用 TDD 集成第 3 部分 API,因此我正在实现一个 HttpClient 包装器接口,它公开了可能的 api 调用等等。

我想测试是否在 post 方法中发送了正确的负载,但是当我尝试从我注入的假 HttpMessageHandler 中读取字符串内容时,我得到一个 ObjectDisposedException .有没有更好的方法来测试这个?

测试代码:

[Fact]
public async void PostSignupRequest_RequestSent_PostedSerializedRequestAsContent()
{
    var client = MakeOnboardingClient();
    _fakeJsonSerializer.SerializedResult = "some json";

    await client.PostSignupRequest(_someSignupRequest);

    Assert.Equal("some json", await _fakeMessageHandler.Request.Content.ReadAsStringAsync());
}

我的 HttpMessageHandler spy/test 双:

public class FakeHttpMessageHandler : HttpMessageHandler
{
    public HttpRequestMessage Request;
    public string ResponseContent = string.Empty;

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        Request = request;
        return await Task.FromResult(new HttpResponseMessage
        {
            Content = new StringContent(ResponseContent)
        });
    }
}

生产代码:

public async Task<SignupRequestResponse> PostSignupRequest(SignupRequest request)
{
    var json = _jsonSerializer.Serialize(request);
    await _httpClient.PostAsync(/* url */, new StringContent(json));
    return null;
}

我现在找到了修复方法。在我的 HttpMessageHandler fake 中,我现在不仅保存请求,还显式保存内容字符串(由于 HttpClient 尚未处理请求,因此可以在此时提取)。我的假货现在看起来像这样:

public class FakeHttpMessageHandler : HttpMessageHandler
{
    public HttpRequestMessage Request;
    public string LastRequestString = string.Empty;
    public string ResponseContent = string.Empty;

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
        CancellationToken cancellationToken)
    {
        if (request.Content != null) // needed this to prevent some NPEs in other tests, YMMV
        {
            LastRequestString = await request.Content.ReadAsStringAsync();
        }
        Request = request;
        return await Task.FromResult(new HttpResponseMessage
        {
            Content = new StringContent(ResponseContent)
        });
    }
}