Files
App-vNext-Polly/test/Polly.Core.Tests/Simmy/Fault/FaultGeneratorTests.cs
T
dualfroz fa219d839e fix(simmy): return null from FaultGenerator when no fault is generated
FaultGenerator's implicit conversion dereferenced the nullable Outcome
returned by the underlying generator via `!.Value`, throwing
InvalidOperationException ("Nullable object must have a value.") when the
generator produced no outcome - an empty generator, or registered weights
summing to zero. ChaosFaultStrategy treats a null fault as "do not inject"
and only catches OperationCanceledException, so the exception escaped and
failed the execution the strategy was meant to leave untouched.

Propagate the nullable outcome with `?.Exception`, mirroring
OutcomeGenerator<TResult>, so no fault is injected when none is generated.
2026-09-02 11:43:55 +02:00

69 lines
1.7 KiB
C#

using Polly.Simmy.Fault;
namespace Polly.Core.Tests.Simmy.Fault;
public class FaultGeneratorTests
{
[Fact]
public void AddException_Generic_Ok()
{
var generator = new FaultGenerator();
generator.AddException<InvalidOperationException>();
Generate(generator).ShouldBeOfType<InvalidOperationException>();
}
[Fact]
public void AddException_Factory_Ok()
{
var generator = new FaultGenerator();
generator.AddException(() => new InvalidOperationException());
Generate(generator).ShouldBeOfType<InvalidOperationException>();
}
[Fact]
public void AddException_FactoryWithResilienceContext_Ok()
{
var generator = new FaultGenerator();
generator.AddException(context =>
{
context.ShouldNotBeNull();
return new InvalidOperationException();
});
Generate(generator).ShouldBeOfType<InvalidOperationException>();
}
[Fact]
public void NoExceptionRegistered_ShouldReturnNull()
{
var generator = new FaultGenerator();
Generate(generator).ShouldBeNull();
}
[Fact]
public void AllWeightsZero_ShouldReturnNull()
{
var generator = new FaultGenerator();
generator.AddException<InvalidOperationException>(weight: 0);
Generate(generator).ShouldBeNull();
}
private static Exception? Generate(FaultGenerator generator)
{
Func<FaultGeneratorArguments, ValueTask<Exception?>> func = generator;
return func(
new FaultGeneratorArguments(
ResilienceContextPool.Shared.Get(TestCancellation.Token))).AsTask().Result;
}
}