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

时间:2015-11-20 15:52:23

标签: c# mocking tdd

我正在使用TDD集成第三方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间谍/测试双:

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;
}

1 个答案:

答案 0 :(得分:1)

我现在找到了修复方法。在我的HttpMessageHandler中,假设我现在不保存请求,我还明确保存了内容字符串(由于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)
        });
    }
}