12

I'm stuck with what I thought was an easy example. I want to assert that a collection of objects contains an object that is equivalent to a given object. like: col.ShouldContainEquivalentTo(obj)

var objectList1 = new List<SomeClass> { new SomeClass("A"), new SomeClass("B"), new SomeClass("C") };
var objectList2 = new List<SomeClass> { new SomeClass("C"), new SomeClass("B"), new SomeClass("A") };

objectList1.ShouldAllBeEquivalentTo(objectList2); //this works
objectList2.ShouldContainEquivalentTo(new SomeClass("B")); //method does not exist. How can I achieve sthg like that

I want to compare based on the objects values - just like how ShouldBeEquivalentTo and ShouldAllBeEquivalentTo work. Should not be necessary to write my own equality comparer.

BR Matthias

Matthias
  • 1,267
  • 1
  • 15
  • 27

4 Answers4

25

I finally had the time to implement this feature and it is now available with version 5.6.0 of FluentAssertions.

This now works!

var objectList = new List<SomeClass> { new SomeClass("A"), new SomeClass("B"), new SomeClass("C") };
objectList.Should().ContainEquivalentOf(new SomeClass("A"));

BR Matthias

Matthias
  • 1,267
  • 1
  • 15
  • 27
  • Well, now I'd like to supply an IEnumerable to verify that the equivalent of all supplied objects exist. – comecme Jul 27 '21 at 15:14
  • Well, now I'd like something like `dictionary.Should().ContainKeyEquivalentOf("key").WhoseValue.Should().Be("something");;` – user1007074 May 03 '23 at 23:00
6

Its possible now. See accepted answer. Stop upvoting this workaround. ^^


It seems like I was too naive and there is in fact no method that does quite what I want to have. Thx @Nkosi for pointing out.

Just to round this topic up: We ended up with something like

objectList.Should().Contain(dto=>dto.Id == expectedDto.Id).Which.ShouldBeEquivalentTo(expectedDto)

This only works (edit: beautifully) when you have some kind of unique identifier (id, name, etc.). But at least it uses the build in ShouldBeEquivalentTo for all the other properties!

I created a feature request.

Thx for all the input!

BR Matthias

Matthias
  • 1,267
  • 1
  • 15
  • 27
2

You can use the already available functionality of framework to achieve the desired behavior

This is an ugly hack but should get the job done.

public static class FluentAssertionsEx {

    public static void ShouldContainEquivalentTo<T>(this IEnumerable<T> subject, object expectation, string because = "Expected subject to contain equivalent to provided object", params object[] becauseArgs) {
        var expectedCount = subject.Count();
        var actualCount = 0;
        try {
            foreach (var item in subject) {
                item.ShouldBeEquivalentTo(expectation);
            }
        } catch {
            actualCount++;
        }
        expectedCount.Should().NotBe(actualCount, because, becauseArgs);
    }
}
Nkosi
  • 235,767
  • 35
  • 427
  • 472
1

You could do something like:

objectList2.Should().Contain(x => x.Property == "B");

where Property is replaced by whichever property is set by the constructor of SomeClass.

Richard Pickett
  • 482
  • 8
  • 17
  • The "B" was just an example to demonstrate the difference. In a real scenario there would be a lot of properties. Plus, writing it like that is more or less the same as writing an equality comparer. Imho there should already be a generic solution because `ShouldBeEquivalentTo` and `ShouldAllBeEquivalentTo` already work that way. – Matthias Jun 28 '17 at 22:54
  • You can also do `objectList2.Should().Contain(new SomeClass("B"))` This will apply the equals on all the properties. Note that you will have to implement GetHashCode() for SomeClass. [Why is it important to override GetHashCode when Equals method is overridden?](https://stackoverflow.com/questions/371328/why-is-it-important-to-override-gethashcode-when-equals-method-is-overridden) – CBinet Jun 28 '17 at 22:55
  • 1
    @Matthias do not make that assumption. That functionality does not exist at the moment. You could always raise an issue or feature request with the developer on githib. – Nkosi Jun 28 '17 at 22:56