Adv*_*emy 0 .net c# xunit nsubstitute
我想在我的 UT 中测试我的 httpclient post 重试功能,这里我模拟了 HttpFactory:
第一次和第二次,HttpFactory 总是返回 HttpStatusCode.InternalServerError
public class MyServiceClient
{
private readonly IHttpClientFactory _clientFactory;
public MyServiceClient(IHttpClientFactory clientFactory)
{
_clientFactory = clientFactory;
}
public async Task<string> GetResponse(string test= "te")
{
using var client = _clientFactory.CreateClient("MyClient");
var content = new StringContent("{}", Encoding.UTF8, "application/json");
var response = await client.PostAsync("http://www.contoso.com/",content);
if (!response.IsSuccessStatusCode)
{
throw new ApplicationException("Application Error!");
}
var result = await response.Content.ReadAsStringAsync();
return result;
}
public async Task<string> PollyExecute()
{
try
{
var policy = Policy
.Handle<Exception>()
.WaitAndRetryAsync(3,
count => TimeSpan.FromSeconds(2),
(ex, timeSpan,retrycount, context) =>
{
Console.WriteLine(ex);
});
var response = await policy.ExecuteAsync(()=>GetResponse());
return response;
}
catch (Exception e)
{
Console.WriteLine(e);
throw ;
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后我使用我的策略来运行客户端 postasync 方法,我第一次重试没有问题,我得到了例外的 500 内部服务器错误。
public class HttpClientTest
{
[Fact]
public async Task PoliceTest()
{
var messageHandler = new StubHttpMessageHandler(HttpStatusCode.InternalServerError, "Error!!!!");
var httpClient = new HttpClient(messageHandler)
{
BaseAddress = new Uri("http://mockuri")
};
var factory = Substitute.For<IHttpClientFactory>();
factory.CreateClient(Arg.Any<string>()).Returns(httpClient, httpClient);
var client = new MyServiceClient(factory);
var result = await client.PollyExecute();
}
}
public sealed class StubHttpMessageHandler : HttpMessageHandler
{
public string _response;
public HttpStatusCode _statusCode;
public StubHttpMessageHandler(HttpStatusCode statusCode, string response)
{
_statusCode = statusCode;
_response = response;
}
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
CancellationToken cancellationToken)
{
return Task.FromResult(Send(request));
}
private HttpResponseMessage Send(HttpRequestMessage request)
{
return new HttpResponseMessage
{
Content = new StringContent(_response),
StatusCode = _statusCode,
};
}
}
Run Code Online (Sandbox Code Playgroud)
但是,在第二次重试中,运行 postasync 方法时,
为什么?有朋友知道原因吗?提前致谢!
我认为您只是IHttpClientFactory在测试设置中错误地嘲笑。根据设计,工厂返回新客户端的默认实现(Microsoft docs):
每次调用 CreateClient(String) 都保证返回一个新的 HttpClient 实例。调用者可以无限期地缓存返回的 HttpClient 实例或将其使用包含在 using 块中以在需要时处置它。
在示例中,您提供的工厂返回与httpClient第一次使用后处理的相同。模拟工厂一次又一次地返回相同的已处理对象,从而导致已处理错误。只需修改您的示例以返回客户端的不同实例(请原谅重复的代码)即可避免已处理的错误:
...
var httpClient = new HttpClient(messageHandler)
{
BaseAddress = new Uri("http://mockuri")
};
var httpClient1 = new HttpClient(messageHandler)
{
BaseAddress = new Uri("http://mockuri")
};
var httpClient2 = new HttpClient(messageHandler)
{
BaseAddress = new Uri("http://mockuri")
};
var httpClient3 = new HttpClient(messageHandler)
{
BaseAddress = new Uri("http://mockuri")
};
var factory = Substitute.For<IHttpClientFactory>();
factory
.CreateClient(Arg.Any<string>())
.Returns(httpClient, httpClient1, httpClient2, httpClient3);
...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
170 次 |
| 最近记录: |