1

So I have to use a library that takes a HttpClient, and may throw a throttling exception in case of a 429 response from the remote system.

I'd like to test a Polly policy that would back off for the requested amount of seconds, but I can't figure out how to modify the test to add a Polly policy.

I looked at this SO question, but my circumstances are different: Testing Polly retry policy with moq

Here's the test that verifies the exception is thrown. I would like to make a different version with a Polly retry policy that won't throw.

using Moq;
using Moq.Protected;
using Polly;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

[TestClass]
public class SIGSClientTests
{

    [TestMethod]
    public async Task SigsThrowsOn429()
    {
        var resp = new HttpResponseMessage
        {
            StatusCode = (HttpStatusCode)429,
            Content = new StringContent("{}"),
        };

        resp.Headers.Add("Retry-After", "42");

        var mockMessageHandler = new Mock<HttpMessageHandler>();
        mockMessageHandler.Protected()
            .Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>())
            .ReturnsAsync(resp);

        var client = new HttpClient(mockMessageHandler.Object);

        // Presumably I can create a Polly retry policy here, and add it to the HttpClient?
        // And then add a 2nd OK response and get rid of the try-catch?

        Uri substrateurl = new Uri("https://substrate.office.com/");
        try {
            await SIGSClient.Instance.PostAsync(client, substrateurl, new UserInfo(), "faketoken", new Signal(), Guid.NewGuid());
        }
        catch (SigsThrottledException e)
        {
            Assert.AreEqual(e.RetryAfterInSeconds, (uint)42);
        }
    }

I have a fair idea of how to create the Polly retry policy, but it seems all the unit test examples I can find expect that I use a HttpClientFactory to make the client, in which case I am not sure how to make THAT pump out the mock client.

Peter Csala
  • 17,736
  • 16
  • 35
  • 75
  • Maybe the following answer can help you: https://stackoverflow.com/questions/69945866/how-to-mock-httpclient-from-ihttpclientfactory-combined-with-polly-policies-in/ – quervernetzt Nov 12 '21 at 16:13
  • As you have stated in your answer you can't unit it? Why because HttpClient and the policy are not two independent dependencies. The latter decorates the former, so at the end you have a single dependency. If you mock that you only mock the HttpClient. So you should look for integration testing instead. – Peter Csala Jul 29 '22 at 19:31

1 Answers1

0

There's no way that I can find to inject a policy of this kind into a HttpClient if HttpClientFactory instance, so you'll have to use it explicitly like in this example.