0

My goal is to use fluent assertions to collect all assertion failures and report them.

Currently, I use

private static void AssertValue(object? actual, object? expected, string fieldName, IDictionary<string, string> assertionFailures)
{
    try
    {
        using (new AssertionScope(fieldName))
        {
            actual.Should().BeEquivalentTo(expected);
        }
    }
    catch (Exception e)
    {
        assertionFailures.Add(fieldName, e.Message);
    }
}

Is there a way to do this using different way not involving catching an Exception?

Patrik Mihalčin
  • 3,341
  • 7
  • 33
  • 68

1 Answers1

0

You could use a custom assertion strategy with an assertionscope and do it that way.

Something like this:

[Fact]
public void Should_return_failures()
{
    var actual = string.Empty;

    var collectFailuresStrategy = new CollectFailuresStrategy(out var failures);
    using (new AssertionScope(collectFailuresStrategy))
    {
        actual.Should().NotBeEmpty();
        actual.Should().Be("actual");
    }


    failures.Should().HaveCount(2);

}


private class CollectFailuresStrategy : IAssertionStrategy
{
    private readonly List<string> _failures;

    public CollectFailuresStrategy(out List<string> failures)
    {
        failures = new List<string>();
        _failures = failures;
    }

    public IEnumerable<string> FailureMessages => _failures;

    public void HandleFailure(string message)
    {
        _failures.Add(message);
    }

    public IEnumerable<string> DiscardFailures()
    {
        var discardedFailures = _failures.ToArray();
        _failures.Clear();
        return discardedFailures;
    }

    public void ThrowIfAny(IDictionary<string, object> context)
    {
        //if you still want the test to fail, you would do something like:
        //if (_failures != null)
        //{
        //    Services.ThrowException(string.Join(',', _failures));
        //}
    }
}
NiSø
  • 44
  • 5