public async Task HttpClientPolicy_CombinePolicies_BehavesAccordingToPolicy() { var retryCount = 3; var exceptionAllowedBeforeBreaking = retryCount + 2; var circuitBreakDurationInMs = 10000; var timeoutInSeconds = 25; var foo = new FooStub(); var policy = HttpClientPollyPolicy.Initialise() .AddWaitRetryPolicy(retryCount) .AddFallbackPolicy(() => foo.FakeCallback()) .AddCircuitBreakerPolicy(exceptionAllowedBeforeBreaking, TimeSpan.FromMilliseconds(circuitBreakDurationInMs)) .AddTimeoutPolicy(timeoutInSeconds) .Build(); Func <bool, int?, Task <HttpResponseMessage> > barAsync = (bool returnFailureMessage, int?fakeTimeoutInSeconds) => policy.ExecuteAsync(() => foo.BarAsync(returnFailureMessage, fakeTimeoutInSeconds)); var result = await barAsync(true, null); int barAsyncMethodInvocationCount = retryCount + 1; Assert.Equal(HttpStatusCode.BadRequest, result.StatusCode); result = await barAsync(true, null); barAsyncMethodInvocationCount++; int callbackMethodInvocationCount = 3; Assert.Equal(HttpStatusCode.BadRequest, result.StatusCode); await Task.Delay(circuitBreakDurationInMs); //Return unhandled error code to transition circuit from half-open to close result = await barAsync(false, null); barAsyncMethodInvocationCount++; Assert.Equal(HttpStatusCode.OK, result.StatusCode); result = await barAsync(true, null); barAsyncMethodInvocationCount += retryCount + 1; Assert.Equal(HttpStatusCode.BadRequest, result.StatusCode); result = await barAsync(true, timeoutInSeconds); barAsyncMethodInvocationCount++; callbackMethodInvocationCount++; Assert.Equal(HttpStatusCode.BadRequest, result.StatusCode); Assert.Equal(callbackMethodInvocationCount, foo.FallbackCount); Assert.Equal(barAsyncMethodInvocationCount, foo.BarAsyncCount); }