I've been having some trouble with FluentAssertions lately, and after playing around with it a little bit, it seems like there is some sort of bug that may have something to do with Guid
s. Here's the code that throws an error:
class Dto
{
public Guid Id { get; set; }
public string Name { get; set; }
}
[TestMethod]
public void TestTest()
{
var dto1 =
new List<Dto>
{
new Dto { Id = Guid.NewGuid(), Name = "Name" }
};
var dto2 =
new List<Dto>
{
new Dto { Id = Guid.NewGuid(), Name = "Name" }
};
var list1 = new List<List<Dto>> { dto1, dto2 };
var list2 = new List<List<Dto>> { dto2, dto1 };
list1.ShouldAllBeEquivalentTo(list2);
}
Note the reversed order in list1
and list2
, which is essential to reproduce the error:
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.FormatException: Index (zero based) must be greater than or equal to zero and less than the size of the argument list. Result StackTrace:
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) in C:\projects\fluentassertions-vf06b\Src\Core\Execution\MessageBuilder.cs:line 66 at FluentAssertions.Execution.MessageBuilder.Build(String message, Object[] messageArgs, String reason, ContextDataItems contextData) in C:\projects\fluentassertions-vf06b\Src\Core\Execution\MessageBuilder.cs:line 39 at FluentAssertions.Execution.AssertionScope.FailWith(String message, Object[] args) in C:\projects\fluentassertions-vf06b\Src\Core\Execution\AssertionScope.cs:line 190 at FluentAssertions.Equivalency.EnumerableEquivalencyValidator.LooselyMatchAgainst[T](IList`1 subjects, Object expectation, Int32 expectationIndex) in C:\projects\fluentassertions-vf06b\Src\Core\Equivalency\EnumerableEquivalencyValidator.cs:line 123 at FluentAssertions.Equivalency.EnumerableEquivalencyValidator.AssertElementGraphEquivalency[T](T[] subjects, Object[] expectations) in C:\projects\fluentassertions-vf06b\Src\Core\Equivalency\EnumerableEquivalencyValidator.cs:line 79 at FluentAssertions.Equivalency.EnumerableEquivalencyValidator.Execute[T](T[] subject, Object[] expectation) in C:\projects\fluentassertions-vf06b\Src\Core\Equivalency\EnumerableEquivalencyValidator.cs:line 39 at lambda_method(Closure ) --- End of inner exception stack trace --- at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments) at System.Delegate.DynamicInvokeImpl(Object[] args) at FluentAssertions.Equivalency.GenericEnumerableEquivalencyStep.Handle(IEquivalencyValidationContext context, IEquivalencyValidator parent, IEquivalencyAssertionOptions config) in C:\projects\fluentassertions-vf06b\Src\Core\Equivalency\GenericEnumerableEquivalencyStep.cs:line 61 at FluentAssertions.Equivalency.EquivalencyValidator.AssertEqualityUsing(IEquivalencyValidationContext context) in C:\projects\fluentassertions-vf06b\Src\Core\Equivalency\EquivalencyValidator.cs:line 63 at FluentAssertions.Equivalency.EnumerableEquivalencyValidator.TryToMatch[T](T subject, Object expectation, Int32 expectationIndex) in C:\projects\fluentassertions-vf06b\Src\Core\Equivalency\EnumerableEquivalencyValidator.cs:line 133 at FluentAssertions.Equivalency.EnumerableEquivalencyValidator.LooselyMatchAgainst[T](IList`1 subjects, Object expectation, Int32 expectationIndex) in C:\projects\fluentassertions-vf06b\Src\Core\Equivalency\EnumerableEquivalencyValidator.cs:line 106 at FluentAssertions.Equivalency.EnumerableEquivalencyValidator.AssertElementGraphEquivalency[T](T[] subjects, Object[] expectations) in C:\projects\fluentassertions-vf06b\Src\Core\Equivalency\EnumerableEquivalencyValidator.cs:line 79 at FluentAssertions.Equivalency.EnumerableEquivalencyValidator.Execute[T](T[] subject, Object[] expectation) in C:\projects\fluentassertions-vf06b\Src\Core\Equivalency\EnumerableEquivalencyValidator.cs:line 39 at lambda_method(Closure ) --- End of inner exception stack trace --- at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments) at System.Delegate.DynamicInvokeImpl(Object[] args) at FluentAssertions.Equivalency.GenericEnumerableEquivalencyStep.Handle(IEquivalencyValidationContext context, IEquivalencyValidator parent, IEquivalencyAssertionOptions config) in C:\projects\fluentassertions-vf06b\Src\Core\Equivalency\GenericEnumerableEquivalencyStep.cs:line 61 at FluentAssertions.Equivalency.EquivalencyValidator.AssertEqualityUsing(IEquivalencyValidationContext context) in C:\projects\fluentassertions-vf06b\Src\Core\Equivalency\EquivalencyValidator.cs:line 63 at FluentAssertions.Equivalency.EquivalencyValidator.AssertEquality(EquivalencyValidationContext context) in C:\projects\fluentassertions-vf06b\Src\Core\Equivalency\EquivalencyValidator.cs:line 35 at FluentAssertions.AssertionExtensions.ShouldAllBeEquivalentTo[T](IEnumerable`1 subject, IEnumerable expectation, Func`2 config, String because, Object[] becauseArgs) in C:\projects\fluentassertions-vf06b\Src\Shared\AssertionExtensions.cs:line 680 at FluentAssertions.AssertionExtensions.ShouldAllBeEquivalentTo[T](IEnumerable`1 subject, IEnumerable expectation, String because, Object[] becauseArgs) in C:\projects\fluentassertions-vf06b\Src\Shared\AssertionExtensions.cs:line 637 at (Where my code is)
Sorry for the long stack trace, but I wanted to include anything that might be relevant.
What's going on here? Is there something I'm missing?