-
Notifications
You must be signed in to change notification settings - Fork 732
Global AssertEquivalencyUsing have no effect for record types without public members #1977
Copy link
Copy link
Closed
Labels
Description
Description
Using static method AssertionOptions.AssertEquivalencyUsing to configure comparison by value for one specific record type doesn't work. Instances are still compared by member.
Record type is a type without public members
public record Position
{
public static Position None = new(0);
public static Position One = new(1);
public static Position Two = new(2);
private readonly int _value;
private Position(int value)
{
_value = value;
}
}
// Wrapper class
public class Player
{
public string Name { get; }
public Position Position { get; }
public Player(string name, Position position)
{
Name = name;
Position = position;
}
}Explicitly provided configuration works as expected
// Pass
Position.Two.Should().NotBeEquivalentTo(Position.One, o => o.ComparingByValue(typeof(Position)));
// Pass
var player1 = new Player("First", Position.One);
var player2 = new Player("First", Position.Two);
player1.Should().NotBeEquivalentTo(player2, o => o.ComparingByValue(typeof(Position)));Complete minimal example reproducing the issue
Configuring comparison behaviour "globally" via static AssertionOptions.AssertEquivalencyUsing doesn't work
AssertionOptions.AssertEquivalencyUsing(
options => options.ComparingByValue(typeof(Position))
);
// Fail
Position.Two.Should().NotBeEquivalentTo(Position.None);
var player1 = new Player("First", Position.One);
var player2 = new Player("First", Position.Two);
// Fail
player1.Should().NotBeEquivalentTo(player2);Expected behavior:
Expect tests in "complete minimal example" to pass
Actual behavior:
Tests are failing with corresponding exceptions
AssertionOptions.AssertEquivalencyUsing(options => options.ComparingByValue(typeof(Position)));
Position.Two.Should().NotBeEquivalentTo(Position.None);
// Exception
System.InvalidOperationException
No members were found for comparison. Please specify some members to include in the comparison or choose a more meaningful assertion.
at FluentAssertions.Equivalency.Steps.StructuralEqualityEquivalencyStep.Handle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator)
at FluentAssertions.Equivalency.EquivalencyValidator.RunStepsUntilEquivalencyIsProven(Comparands comparands, IEquivalencyValidationContext context)
at FluentAssertions.Equivalency.EquivalencyValidator.RecursivelyAssertEquality(Comparands comparands, IEquivalencyValidationContext context)
at FluentAssertions.Equivalency.EquivalencyValidator.AssertEquality(Comparands comparands, EquivalencyValidationContext context)
at FluentAssertions.Primitives.ObjectAssertions`2.BeEquivalentTo[TExpectation](TExpectation expectation, Func`2 config, String because, Object[] becauseArgs)
at FluentAssertions.Primitives.ObjectAssertions`2.NotBeEquivalentTo[TExpectation](TExpectation unexpected, Func`2 config, String because, Object[] becauseArgs)
at FluentAssertions.Primitives.ObjectAssertions`2.NotBeEquivalentTo[TExpectation](TExpectation unexpected, String because, Object[] becauseArgs)Within wrapper type
var player1 = new Player("First", Position.One);
var player2 = new Player("First", Position.Two);
player1.Should().NotBeEquivalentTo(player2);
// Exception
Xunit.Sdk.XunitException
Expected player1 not to be equivalent to EncapsulatedRecordTests.Player
{
Name = "First",
Position = Position { }
}, but they are.
at FluentAssertions.Execution.XUnit2TestFramework.Throw(String message)
at FluentAssertions.Execution.TestFrameworkProvider.Throw(String message)
at FluentAssertions.Execution.DefaultAssertionStrategy.HandleFailure(String message)
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.Primitives.ObjectAssertions`2.NotBeEquivalentTo[TExpectation](TExpectation unexpected, Func`2 config, String because, Object[] becauseArgs)
at FluentAssertions.Primitives.ObjectAssertions`2.NotBeEquivalentTo[TExpectation](TExpectation unexpected, String because, Object[] becauseArgs)Versions
- Which version of Fluent Assertions are you using?
6.7.0 - Which .NET runtime and version are you targeting? E.g. .NET framework 4.6.1 or .NET Core 2.1.
net6.0
Additional Information
Reactions are currently unavailable