You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何验证传递给HttpClient.PostAsJsonAsync的请求对象?

解决方案

原测试代码的问题在于错误地在SendAsync的验证参数中添加了SearchRequest类型的匹配项——SendAsync方法的参数只有HttpRequestMessage和CancellationToken,根本不存在SearchRequest参数,这导致验证逻辑完全不生效。

正确的思路是:PostAsJsonAsync会将SearchRequest序列化为HttpRequestMessage的Content内容,因此需要从HttpRequestMessage中读取并反序列化出SearchRequest对象,再验证其属性值。

修改后的测试代码

public async Task Test()
{
    // Arrange
    var handlerMock = new Mock<HttpClientHandler>();
    handlerMock.Protected()
        .Setup<Task<HttpResponseMessage>>(
            "SendAsync",
            ItExpr.IsAny<HttpRequestMessage>(),
            ItExpr.IsAny<CancellationToken>()
        )
        .ReturnsAsync(new HttpResponseMessage
        {
            StatusCode = HttpStatusCode.OK,
            Content = new StringContent("{'foo':'bar'}", Encoding.UTF8, "application/json")
        });
    httpClient = new HttpClient(handlerMock.Object);

    // Act
    var criteria = new Criteria();
    await SomeMethodToTestAsync(criteria);

    // Assert
    var expectedPublishedDate = new DateOnly(2021, 10, 17);
    handlerMock.Protected().Verify(
        "SendAsync",
        Times.Exactly(1),
        ItExpr.Is<HttpRequestMessage>(req =>
            req.Method == HttpMethod.Post &&
            req.RequestUri.ToString() == "https://example.com" && // 可选:验证请求URL
            ValidateSearchRequestContent(req.Content, expectedPublishedDate)
        ),
        ItExpr.IsAny<CancellationToken>()
    );
}

private bool ValidateSearchRequestContent(HttpContent content, DateOnly expectedDate)
{
    // 读取Content中的JSON字符串
    var jsonContent = content.ReadAsStringAsync().Result;
    // 反序列化为SearchRequest对象(注意匹配序列化配置)
    var searchRequest = JsonSerializer.Deserialize<SearchRequest>(jsonContent, new JsonSerializerOptions
    {
        PropertyNameCaseInsensitive = true, // 避免JSON属性大小写不匹配问题
        Converters = { new DateOnlyConverter() } // 如果需要自定义DateOnly序列化,添加对应的转换器
    });

    // 验证目标属性
    return searchRequest != null && searchRequest.PublishedDateStart == expectedDate;
}

关键说明

  1. 移除错误的参数匹配:删除原代码中ItExpr.Is<SearchRequest>(...)这一行,因为SendAsync没有该参数。
  2. 从Content中解析请求对象:通过HttpContent.ReadAsStringAsync()读取序列化后的JSON,再反序列化为SearchRequest,之后验证属性值。
  3. 匹配序列化配置:如果待测试方法中使用了自定义的JSON序列化配置(比如Newtonsoft.Json而非System.Text.Json),需要在反序列化时使用对应的工具(如JsonConvert.DeserializeObject),确保解析结果正确。
  4. 可选的URL验证:添加req.RequestUri.ToString() == "https://example.com"可以进一步验证请求的目标地址是否正确。

内容的提问来源于stack exchange,提问作者arjun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 10:35:06