question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

When chaining ContainsSingle, assertion failed because of FormatException inside FluentAssertion instead of actual difference

See original GitHub issue

Description

When chaining ContainsSingle, assertion failed because of FormatException inside FluentAssertion instead of actual difference.

Complete minimal example reproducing the issue

using FluentAssertions;
using Microsoft.AspNetCore.Mvc.ModelBinding;

[Test]
public void Failed_On_FormatException_Inside_FluentAssertions_When_Strings_Are_Different()
{
    string propertyName = "APropertyName";
    string value = "A value";
    ModelStateDictionary modelState = new ModelStateDictionary();

    modelState.AddModelError(propertyName, $"The value '{value}' is invalid and more characters to be different than expected.");

    modelState.Should().HaveCount(1)
        .And.ContainSingle(kvp => kvp.Key == propertyName)
        .Which.Value.Errors.Should().HaveCount(1)
        .And.ContainSingle(modelError =>
            string.Equals(modelError.ErrorMessage, $"The value '{value}' is invalid."));
}

[Test]
public void Succeed_When_Strings_Are_Same()
{
    string propertyName = "APropertyName";
    string value = "A value";
    ModelStateDictionary modelState = new ModelStateDictionary();

    modelState.AddModelError(propertyName, $"The value '{value}' is invalid.");

    modelState.Should().HaveCount(1)
        .And.ContainSingle(kvp => kvp.Key == propertyName)
        .Which.Value.Errors.Should().HaveCount(1)
        .And.ContainSingle(modelError =>
            string.Equals(modelError.ErrorMessage, $"The value '{value}' is invalid."));
}

Expected behavior:

Failed_On_FormatException_Inside_FluentAssertions_When_Strings_Are_Different test should failed because actual string is different of expected string.

Actual behavior:

Failed_On_FormatException_Inside_FluentAssertions_When_Strings_Are_Different test failed on System.FormatException.

System.FormatException : Index (zero based) must be greater than or equal to zero and less than the size of the argument list.
   at System.Text.StringBuilder.AppendFormatHelper(IFormatProvider provider, String format, ParamsArray args)
   at System.String.FormatHelper(IFormatProvider provider, String format, ParamsArray args)
   at System.String.Format(String format, Object[] args)
   at FluentAssertions.Execution.MessageBuilder.FormatArgumentPlaceholders(String failureMessage, Object[] failureArgs)
   at FluentAssertions.Execution.MessageBuilder.Build(String message, Object[] messageArgs, String reason, ContextDataItems contextData, String identifier, String fallbackIdentifier)
   at FluentAssertions.Execution.AssertionScope.<>c__DisplayClass30_0.<FailWith>b__0()
   at FluentAssertions.Execution.AssertionScope.FailWith(Func`1 failReasonFunc)
   at FluentAssertions.Execution.AssertionScope.FailWith(Func`1 failReasonFunc)
   at FluentAssertions.Execution.AssertionScope.FailWith(String message, Object[] args)
   at FluentAssertions.Collections.SelfReferencingCollectionAssertions`2.ContainSingle(Expression`1 predicate, String because, Object[] becauseArgs)

Versions

  • Which version of Fluent Assertions are you using? 5.10.3

  • Which .NET runtime and version are you targeting? .NET Core 3.1

Additional Information

I tried with FluentAssertions 6.0.0-alpha0001: same behavior as 5.10.3

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:12 (9 by maintainers)

github_iconTop GitHub Comments

1reaction
gceletcommented, Oct 12, 2020

A workaround is to do the string interpolation outside of the predicate.

string expected = $"The value '{value}' is invalid.";
modelState.Should().HaveCount(1)
    .And.ContainSingle(kvp => kvp.Key == propertyName)
        .Which.Value.Errors.Should().HaveCount(1)
        .And.ContainSingle(modelError => modelError.ErrorMessage == expected);

@jnyrup Thank you for this workaround: i’m okay using this workaround for the time being.

0reactions
tjrobinsoncommented, Nov 17, 2020

@tjrobinson The problem described here has been resolved in #1406, but it has not yet been released.

That’s great. thanks. Sorry I totally misread “dennisdoomen closed this in #1406 19 days ago” I thought it had just been closed without a fix.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Capture design guidelines, principles and patterns #1340
When chaining ContainsSingle, assertion failed because of FormatException inside FluentAssertion instead of actual difference #1404.
Read more >
ContainsSingle() assertion fails when collection field is tested
Exception with regular message about failed assertion. Actual behavior: TestProject.UnitTest.Test System.ArgumentNullException: Value cannot be ...
Read more >
FluentAssertions Should().BeEquivalentTo() fails in trivial ...
in the background, and FluentAssertions assumes it should use Equals() instead of property comparisons, because the overridden Equals() is ...
Read more >
Just Use FluentAssertions - Tinkerer
In this post I'm going to compare FluentAssertions to the built-in xUnit assertions, and hopefully convince you to just use FluentAssertions for your...
Read more >
Exceptions
If you are asserting that an exception type other than AggregateException is thrown, an AggregateException must not be thrown, even if it contains...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found