public async Task TearDown() { var result = new Dictionary <string, TState>(); var p = new TProjection(); foreach (var @event in given) { var e = @event.Item2; var type = e.GetType(); var attr = type.GetCustomAttribute <EventTypeIdAttribute>(); if (attr == null) { throw new ArgumentException($"Mark e '{type.FullName}' with {nameof(EventTypeIdAttribute)}"); } var id = attr.Id; var dispatchedEvent = new DispatchedEvent { Event = e, Metadata = new Metadata { EventId = Guid.NewGuid(), EventTypeId = id, StreamId = @event.Item1 } }; var partition = p.GetPartitioningKey(dispatchedEvent); TState state; if (result.TryGetValue(partition, out state) == false) { result[partition] = state = new TState(); } await p.Dispatch(dispatchedEvent, state).ConfigureAwait(false); } var expected = Serialize(then); var observed = Serialize(result); var areEqual = expected.SequenceEqual(observed); if (areEqual == false) { Console.WriteLine("GIVEN:"); using (ConsoleExtensions.Indent()) { Write(given); } Console.WriteLine("THEN should be:"); using (ConsoleExtensions.Indent()) { Write(then); } Console.WriteLine("BUT was:"); using (ConsoleExtensions.Indent()) { Write(result); } TestExecutionContext.CurrentContext.CurrentResult. SetResult(ResultState.ChildFailure, "The state was different from expected.", " "); } }