使用最小起订量测试 Polly 重试策略
Posted
技术标签:
【中文标题】使用最小起订量测试 Polly 重试策略【英文标题】:Testing Polly retry policy with moq 【发布时间】:2017-11-17 00:52:14 【问题描述】:我正在尝试为 polly 编写单元测试,但看起来返回被缓存了。
方法 PostAsyncWithRetry:
using Polly;
using System;
using System.Diagnostics;
using System.Net.Cache;
using System.Net.Http;
public class RetryClient
private HttpClient httpClient = new HttpClient(new WebRequestHandler()
CachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore) );
public HttpResponseMessage PostAsyncWithRetry(
String url,
String path,
StringContent httpContent)
httpClient.BaseAddress = new Uri(url);
var retryPolicy =
Policy.Handle<HttpRequestException>()
.OrResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode)
.RetryAsync(3, (exception, retryCount, context) =>
Debug.WriteLine("RetryCount: 0", retryCount);
);
var response = retryPolicy.ExecuteAsync(async () =>
return await httpClient.PostAsync(path, httpContent);
);
return response.Result;
测试:
[TestFixture]
class Test
private HttpClient mockHTTPClient;
private Mock<WebRequestHandler> mockHttpMessageHandler;
private RetryClient testInstance;
private const String URL = "https://aaa.com";
private const String PATH = "/path";
private const String EXPECTED_STRING_CONTENT = "Some return text";
[SetUp]
public void SetUp()
testInstance = new RetryClient();
mockHttpMessageHandler = new Mock<WebRequestHandler>();
mockHttpMessageHandler.Object.CachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore);
mockHTTPClient = new HttpClient(mockHttpMessageHandler.Object);
var type = typeof(RetryClient);
var fields = type.GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
fields[0].SetValue(testInstance, mockHTTPClient);
[Test]
public void TestMEEEE()
var responses = new Queue<Task<HttpResponseMessage>>();
responses.Enqueue(Task.FromResult(new HttpResponseMessage
StatusCode = HttpStatusCode.NotFound,
Content = new StringContent(EXPECTED_STRING_CONTENT)
));
responses.Enqueue(Task.FromResult(new HttpResponseMessage
StatusCode = HttpStatusCode.OK,
Content = new StringContent(EXPECTED_STRING_CONTENT)
));
var postContent = new StringContent(EXPECTED_STRING_CONTENT);
mockHttpMessageHandler.Protected()
.Setup<Task>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>())
.Returns(responses.Dequeue());
var response = testInstance.PostAsyncWithRetry(
URL, PATH, postContent);
mockHttpMessageHandler.Verify();
Assert.AreEqual(responses.Count, 0, "didn't dequeue");
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode, "Incorrect status code");
不知道为什么,但看起来响应队列只是出队一次,这让我相信响应正在缓存。有谁知道谁在缓存响应,以及如何禁用它?
提前致谢!
【问题讨论】:
请尝试提供真实的minimal reproducible example,因为不清楚这两个片段如何交互。旁注:使用.Result
使方法非异步并可能死锁......但在单元测试中不太可能出现问题。
这里有一些你可以看看:github.com/App-vNext/Polly/blob/master/src/Polly.SharedSpecs/…
@ScottHannen 共享的RetrySpec.cs
的当前网址
【参考方案1】:
我想通了。它与缓存无关。在模拟设置期间,它将 Dequeue 值存储为返回值,而不是每次都调用它。 将其更改为 () =>responses.Dequeue() 现在可以使用。
谢谢你们!
【讨论】:
感谢您提出并回答问题。今天对我帮助很大以上是关于使用最小起订量测试 Polly 重试策略的主要内容,如果未能解决你的问题,请参考以下文章