使用最小起订量测试Polly重试策略 [英] Testing Polly retry policy with moq

查看:148
本文介绍了使用最小起订量测试Polly重试策略的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为波莉编写单元测试,但是看起来返回值已被缓存.

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

PostAsyncWithRetry方法:

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

测试:

[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?

预先感谢一堆!

推荐答案

我知道了.它与缓存无关.在模拟设置期间,它将出队值存储为返回值,而不是每次都调用它. 将其更改为()=>响应.Dequeue()现在可以正常工作.

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.

谢谢你们!

这篇关于使用最小起订量测试Polly重试策略的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆