3

I have several Event classes which implement IEvent. To check actual event against expected event I use

actualEvent.ShouldBeEquivalentTo(expectedEvent,opt => opt.RespectingRuntimeTypes()
                                                         .Excluding(e => e.DateCreated));

The events have a DateCreated property which I ignore as the actual and expected are created at different times.

How do I check if expectedEvent exists at least once in a list of actualEvents?

I would like to do the following;

actualEvents.Should().Contain(expectedEvent,opt => opt.RespectingRuntimeTypes()
                                                      .Excluding(e => e.DateCreated));

but it is not possible.

Can this be done in fluentassertions?

TylerH
  • 20,799
  • 66
  • 75
  • 101
Darren Hall
  • 97
  • 1
  • 1
  • 9

2 Answers2

5

I had a similar scenario where I had a list of items (an object with properties) and I wanted to check if the list contained a local item I was testing for.

I found the solution on this question: FluentAssertions, making sure IEnumerable contains only single element

I simplified my solution by writing the following statement:

FooList.Should().Contain(fooItem, x => true)

The above constraint states the FooList object should contain the fooItem this is expressed with the lambda x => true.

Fairly straight forward and worked for my use case. Give it a try and check out that question thread I linked it may help.

Good luck.

Community
  • 1
  • 1
Trevor
  • 1,561
  • 1
  • 20
  • 28
0

Using FluentAssertions 4.19.4, I solved the problem by implementing my own extension method.

Each element in the collection is asserted individually against the expected element, using the ShouldBeEquivalentTo method which can accept the config argument.

using FluentAssertions.Collections;
using FluentAssertions.Equivalency;
using FluentAssertions.Execution;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

namespace FluentAssertions.Extensions
{
    public static class FluentAssertionsHelper
    {
        public static AndWhichConstraint<TAssertions, T> Contain<TAssertions, T>(this SelfReferencingCollectionAssertions<T, TAssertions> colAssert,
            T expected,
            Func<EquivalencyAssertionOptions<T>, EquivalencyAssertionOptions<T>> config,
            string because = "",
            params object[] becauseArgs) where TAssertions : SelfReferencingCollectionAssertions<T, TAssertions>
        {
            var items = colAssert.Subject;

            if (items == null)
            {
                Execute.Assertion.BecauseOf(because, becauseArgs).FailWith("Expected {context:collection} to contain {0}{reason}, but found {1}.", expected, items);
            }

            var containsItem = false;

            using (var scope = new AssertionScope())
            {
                foreach (var item in items)
                {
                    try
                    {
                        item.ShouldBeEquivalentTo(expected, config, because, becauseArgs);
                    }
                    catch (NullReferenceException) { }

                    var failures = scope.Discard();
                    if (!failures.Any())
                    {
                        containsItem = true;
                        break;
                    }
                }
            }

            if (!containsItem)
            {
                Execute.Assertion.BecauseOf(because, becauseArgs).FailWith("Expected {context:collection} {0} to contain {1}{reason}.", items, expected);
            }

            return new AndWhichConstraint<TAssertions, T>((TAssertions)colAssert, items.Where(item => EqualityComparer<T>.Default.Equals(item, expected)));
        }
    }
}

You can then write the following:

using FluentAssertions;
using FluentAssertions.Extensions;

collection.Should().Contain(item, config => config.Excluding(item => item.MyProperty));
Adam
  • 21
  • 1
  • 4