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.

BeEquivalentTo For().Exclude() does not work for comparison of collections

See original GitHub issue

Description

I have an array or list of nested objects that I would like to check for equivalency. The child objects have some properties that I would like to exclude from the comparison. I’m using the new For().Exclude() syntax. That works fine when comparing individual objects, but it fails when comparing collections.

Complete minimal example reproducing the issue

using FluentAssertions;

public class ForExcludeTest
{
    [Fact]
    public void Test()
    {
        var actualContainer = new Container
        {
            Children = new[]
            {
                new Child
                {
                    ChildId = 20,
                    Name = "Child20"
                }
            }
        };

        var expectedContainer = new Container
        {
            Children = new[]
            {
                new Child
                {
                    ChildId = 20
                }
            }
        };

        // Comparing the actual objects works
        actualContainer.Should().BeEquivalentTo(expectedContainer,
            options => options
                .For(o => o.Children).Exclude(o => o.Name)
            );

        // Comparing the objects inside a list fails
        new List<Container> { actualContainer }.Should().BeEquivalentTo(new List<Container> { expectedContainer },
            options => options
                .For(o => o.Children).Exclude(o => o.Name)
            );
    }

    public class Container
    {
        public Child[] Children { get; set; }
    }

    public class Child
    {
        public int ChildId { get; set; }
        public string Name { get; set; }
    }
}

Expected behavior:

Both assertions should succeed.

Actual behavior:

The second assertion (on a list) fails with the following error:

Expected property root[0].Children[0].Name to be <null>, but found "Child20".

With configuration:
- Use declared types and members
- Compare enums by value
- Compare tuples by their properties
- Compare anonymous types by their properties
- Compare records by their members
- Include non-browsable members
- Include all non-private properties
- Include all non-private fields
- Exclude member Children[]Name
- Match member by name (or throw)
- Be strict about the order of items in byte arrays
- Without automatic conversion.


  Stack Trace: 
XUnit2TestFramework.Throw(String message)
TestFrameworkProvider.Throw(String message)
CollectingAssertionStrategy.ThrowIfAny(IDictionary`2 context)
EquivalencyValidator.AssertEquality(Comparands comparands, EquivalencyValidationContext context)
GenericCollectionAssertions`3.BeEquivalentTo[TExpectation](IEnumerable`1 expectation, Func`2 config, String because, Object[] becauseArgs)
ForExcludeTest.Test() line 38

Versions

  • FluentAssertions 6.7.0
  • .NET 6.0

Issue Analytics

  • State:closed
  • Created a year ago
  • Reactions:3
  • Comments:9 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
jkalmeijcommented, Nov 7, 2022

I am also facing this issue on FluentAssertions 6.8.0.

I worked around it by defining the following class:

        /// <summary>
        /// Work-around for "BeEquivalentTo For().Exclude() does not work for comparison of collections"
        /// https://github.com/fluentassertions/fluentassertions/issues/1989
        /// </summary>
        private class FluentAssertionsIssue1989Workaround
        {
            public FluentAssertionsIssue1989Workaround(List<Container> workaround)
            {
                Workaround = workaround;
            }

            public List<Container> Workaround { get; set; }
        }

and then modifying the assertion:

        new FluentAssertionsIssue1989Workaround(new List<Container> { actualContainer }).Should().BeEquivalentTo(new FluentAssertionsIssue1989Workaround(new List<Container> { expectedContainer }),
            options => options
                .For(o => o.Workaround)
                .For(o => o.Children).Exclude(o => o.Name)
            );
0reactions
abarthocommented, Mar 4, 2023

I agree with @whymatter .

Read more comments on GitHub >

github_iconTop Results From Across the Web

Excluding properties behind an array doesn't work in ...
Should().BeEquivalentTo( expected, cfg => cfg.Excluding(a => a.Items[0]. ... Exclude() does not work for comparison of collections #1989.
Read more >
c# - How to use Exclude in FluentAssertions for property in ...
I want to use fluent assertions to compare to ClassA instances. However I want to ignore the IDs (because the IDs will have...
Read more >
Object graph comparison
If you want to exclude certain (potentially deeply nested) individual members using the Excluding() method: orderDto.Should().BeEquivalentTo(order, ...
Read more >
Releases - Fluent Assertions
NotContainMatch() to assert that the collection does not contain a string that matches a wildcard pattern - #1246. The Using / When option...
Read more >
9 Fluent Assertions Tricks to Save Hours of Your Testing ...
BeEquivalentTo extension method is a powerful way to compare that two objects have the same properties with the same values. The two objects...
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