I am trying to use FluentAssertions to combine collection and object graph comparison assertions.
I have the following class.
public class Contract
{
public Guid Id { get; set; }
public string Name { get; set; }
}
Which are returned in a collection, like so.
ICollection<Contract> contracts = factory.BuildContracts();
I then want to make sure that collection contains only specific Contract
objects.
contracts.Should().Contain(new Contract() { Id = id1, Name = "A" });
This doesn't work, I'm believe because Contain
is using object.Equals
rather than object graph comparison, (as provided by ShouldBeEquivalentTo
).
I also need to assert that the collection doesn't contain a specific object, i.e.
contracts.Should().NotContain(new Contract() { Id = id2, Name = "B" });
Effectively given a collection containing an unknown number of items, I want to ensure that; it contains a number of specific items, and that it doesn't contain a number of specific items.
Can this be achieved using the functions provided by FluentAssertions?
As a side note, I don't want to override object.Equals
for the reasons discussed here. Should I be using IEquatable to ease testing of factories?
It does use the object.Equals
as far as I can tell from documentation and my experience using the framework.
In scenarios like this I tend to use an expression predicate as referenced in the collections documentation for v3.0 and higher.
The following example shows how to make sure that collection contains only specific Contract
objects and also assert that the collection doesn't contain a specific object.
[TestMethod]
public void FluentAssertions_Should_Validate_Collections() {
//Arrange
var id1 = Guid.NewGuid();
var id2 = Guid.NewGuid();
var list = new List<Contract>{
new Contract() { Id = id1, Name = "A" },
new Contract() { Id = Guid.NewGuid(), Name = "B"}
};
var factoryMock = new Mock<IContractFactory>();
factoryMock.Setup(m => m.BuildContracts()).Returns(list);
var factory = factoryMock.Object;
//Act
var contracts = factory.BuildContracts();
//Assert
contracts.Should()
.HaveCount(list.Count)
.And.Contain(c => c.Id == id1 && c.Name == "A")
.And.NotContain(c => c.Id == id2 && c.Name == "B");
}