我使用以下代码模拟HttpClient的HttpClient方法:
var mock = new Mock<HttpMessageHandler>();
Parallel.ForEach(endpoints, (e) =>
{
mock
.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.Is<HttpRequestMessage>(
x => x.RequestUri.AbsolutePath.Contains(e.Endpoint)),
ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(() => new HttpResponseMessage()
{
Content = e.Response
});
});
var client = new HttpClient(mock.Object);其中endpoints是以下类型对象的列表:
class Parameters
{
public string Endpoint { get; }
private readonly string _response;
public StringContent Response
{
get { return new StringContent(_response); }
}
}这种模拟方法如预期的那样工作,但有一个警告。在添加了相当数量的端点后,模拟受保护端点的速度显著下降。我需要模拟客户机的~5000个端点,每个端点都有~2MB的响应。(为更少的端点和更小的数据设计测试似乎很棒,但不幸的是,在我的用例中不是一个选项)。加入~2k端点后,模拟速度明显下降。运行2h后,无法达到~3k端点。
我想知道是否有一种替代的/更好的方法来模拟HttpClient,最好是线性渐近行为。
发布于 2022-01-11 05:23:33
您是否试图通过重写HttpMessageHandler来消除模拟开销?
其他潜在的瓶颈是匹配请求URL和端点响应的Mock<>代码。对于大量的端点,对其进行优化是有意义的(例如,使用MockHttpMessageHandler.SendAsync()来使用字典或查找来查找响应)。
public class MockHttpMessageHandler : HttpMessageHandler
{
private readonly Dictionary<string, HttpContent> _endpoints;
public MockHttpMessageHandler(Dictionary<string, HttpContent> endpoints)
{
_endpoints = endpoints;
}
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
if (_endpoints.TryGetValue(request.RequestUri.ToString(), out var content))
return Task.FromResult(new HttpResponseMessage() { Content = content });
return Task.FromResult(new HttpResponseMessage() { StatusCode = HttpStatusCode.NotFound });
}
}https://stackoverflow.com/questions/70661129
复制相似问题