Testing Polly retry policy with moq

独自空忆成欢 提交于 2020-06-27 14:47:52

问题


I'm trying to write a unit test for polly, but it looks like the return is cached.

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

Test:

[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");
    }

}

Not sure why, but it looks like the responses queue is only being Dequeue once, this leads me to believe the response is being cache. Does anyone know who is caching the response, and how do I disable it?

Thanks a bunch in advance!


回答1:


I figured it out. It has nothing to do with caching. During the mock setup, it stores the Dequeue value as a return instead of invoking it every time. Changing it to () => responses.Dequeue() works now.

Thank you guys!



来源:https://stackoverflow.com/questions/47341598/testing-polly-retry-policy-with-moq

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!