Repost.Client.Testing package holds the test doubles. Add it in your test project:
The stub transport
StubTransport is a scripted, no-network ITransport: enqueue the responses each attempt should return, plug it into the Transport option, send, and assert on what it recorded. The Authorization header is stripped from every recording, and the body bytes are copied verbatim:
SendResult echoes the id, type, customer, and timestamp from the scripted response body.
StubTransport is scripted, not zero-config: an attempt with an empty script faults with InvalidOperationException, a raw transport defect the runtime never retries. Enqueue one response per attempt you expect.Scripting failures and retries
BeyondEnqueueResponse, the transport scripts the other attempt shapes: EnqueueFailure(TransportFailureException) for a classified, retry-eligible network failure, EnqueueException(Exception) for a raw defect, and EnqueuePending() for a response your test completes later through the returned ControlledResponse. To drive a retry test, enqueue two 500s and a 202, raise MaxAttempts, and assert transport.Requests.Count == 3. AwaitRequestCountAsync(count, timeout) waits for in-flight sends to reach a request count.
Deterministic values
Pin the injectable seams to freeze timestamps and generated ids.TestDefaultValueGenerators and TestIdempotencyKeyGenerator provide Fixed, Sequence, and Failing factories:
Now() pinned, the envelope timestamp and every @default(now()) field are fixed — so you can script an exact accepted-response body. The package also ships ManualTimeProvider (a fully deterministic clock you Advance to fire retry timers), DeterministicRetryEntropy (Zero or a scripted jitter sequence), and RecordingObserver (asserts on the lifecycle events the runtime emits).
Continue
Quickstart
The full setup, from install to first send.
Reliability
The delivery states and error codes to exercise in your tests.
Configuration
The options and transport seams in full.