Add simulated network failures ThrowsException/TimesOut (closes #116)#136
Draft
dennisdoomen wants to merge 1 commit into
Draft
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
| } | ||
|
|
||
| [Fact] | ||
| public async Task A_null_exception_is_rejected() |
| /// </remarks> | ||
| /// <param name="exception">The exception to throw for a matching request.</param> | ||
| /// <exception cref="ArgumentNullException">Thrown when <paramref name="exception"/> is <c>null</c>.</exception> | ||
| public RequestMockResponseBuilder ThrowsException(Exception exception) |
| /// configured timeout. The exception is propagated to the caller and the matching request is still recorded in | ||
| /// <see cref="HttpMock.Requests"/> before the exception is thrown. | ||
| /// </remarks> | ||
| public RequestMockResponseBuilder TimesOut() |
| { | ||
| private readonly Func<Exception> exceptionFactory; | ||
|
|
||
| public SimulatedFailureResponder(Func<Exception> exceptionFactory) |
Coverage Report for CI Build 26678769048Coverage increased (+0.2%) to 82.82%Details
Uncovered Changes
Coverage RegressionsNo coverage regressions found. Coverage Stats
💛 - Coveralls |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #116
Stacking
This is the top of a 3-PR stack and targets
dennisdoomen/response-latency-after:After())CancellationTokenthreading)It builds on the async responder path (
TrackRequestAsync,CancellationTokenflowing fromSendAsync→HandleRequest→RequestMock) introduced in those PRs and does not re-implement them.Summary
Adds first-class support for simulating network-level failures so tests can exercise retry, circuit-breaker and error-handling code.
Previously the pipeline swallowed every responder exception and turned it into a
500response, so there was no way to simulate a thrown transport error. This change introduces a dedicated simulated-failure responder that the async pipeline propagates to theHttpClientcaller instead of catching:SimulatedFailureRespondertype represents an intentionally simulated failure.RequestMock.TrackRequestAsyncrecords the request (incrementing the invocation count and adding it to any request collection) and returns the captured request carrying the exception, rather than throwing inline. This guarantees the failed call is recorded inHttpMock.Requests(as expected/handled) before the exception reaches the caller.HttpMock.HandleRequestrethrows the captured exception viaExceptionDispatchInfoafter recording it.try/catchthat converts responder exceptions into a500is carefully scoped so genuine bugs in userRespondsWithresponders keep the current500behavior, while intentionally-simulated failures propagate.Once()/Times(n)andAfter()continue to apply to simulated failures.New public API
Plus
CapturedRequest.SimulatedFailure(Exception?) so a captured entry can be inspected to tell a simulated throw apart from an unexpected500.Usage:
This is additive and backward-compatible. The API verification baselines (
net8.0,net472) were regenerated viaAcceptApiChanges.ps1.Tests
New
WhenSimulatingNetworkFailuresspec class (xUnit + FluentAssertions, AAA) covering:HttpRequestExceptionsurfaces to theHttpClientcaller (generic and specific-instance overloads)TimesOut()throwsTaskCanceledExceptionHttpMock.Requestsand in aCollectingRequestsIncollectionOnce()/Times(n)still apply500All 108 specs pass on both
net8.0andnet472; Release build (warnings-as-errors, all analyzers) is clean.Follow-up
Issue #116 also describes a companion
CapturedRequestAssertions.BeASimulatedFailure()assertion in the separatedennisdoomen/fluentassertions.mocklyrepo (v7/v8 viaShared/). That is not part of this repo/workspace and needs its own PR; the new publicCapturedRequest.SimulatedFailureproperty is exposed here so that assertion can be built on top of it.