Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WithMapping does not map properties of collections #1840

Closed
drewkill32 opened this issue Mar 8, 2022 · 0 comments · Fixed by #1858
Closed

WithMapping does not map properties of collections #1840

drewkill32 opened this issue Mar 8, 2022 · 0 comments · Fixed by #1858
Assignees
Labels

Comments

@drewkill32
Copy link

Description

When using BeEquivalentTo and WithMapping over a collection the properties are not mapped and are ignored.

Complete minimal example reproducing the issue

using FluentAssertions;
using FluentAssertions.Equivalency.Tracing;


var entity = new Entity
{
    Name = "Test",
    EntityId = 1
};

var dto = EntityDto.MapFromEntity(entity);


var entityCol = new[] { entity };
var dtoCol = new[] { dto };



dtoCol.Should().BeEquivalentTo(entityCol, c =>
    c.WithMapping<EntityDto>(s => s.EntityId, d => d.Id)
        .WithTracing());

//     FluentAssertions.Execution.AssertionFailedException: Expectation has property dtoCol[0].EntityId that the other object does not have.
//
//     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 all non-private properties
//     - Include all non-private fields
//     - FluentAssertions.Equivalency.Matching.MappedPathMatchingRule
//     - Match member by name (or throw)
//     - Be strict about the order of items in byte arrays
//     - Without automatic conversion.
//
//     With trace:
//       dtoCol
//       {
//         Structurally comparing System.Object[] and expectation Entity[] at dtoCol
//         {
//           Finding the best match of Entity within all items in System.Object[] at dtoCol[0]
//           {
//             Comparing subject at dtoCol[0] with the expectation at dtoCol[0]
//             {
//               dtoCol[0]
//               {
//                 property dtoCol[0].Name
//                 {
//                   Equivalency was proven by ReferenceEqualityEquivalencyStep
//                 }
//                 Equivalency was proven by StructuralEqualityEquivalencyStep
//               }
//               Contained 1 failures
//             }
//           }
//         }
//         Equivalency was proven by GenericEnumerableEquivalencyStep
//       }
//
//        at FluentAssertions.Execution.FallbackTestFramework.Throw(String message)
//        at FluentAssertions.Execution.TestFrameworkProvider.Throw(String message)
//        at FluentAssertions.Execution.CollectingAssertionStrategy.ThrowIfAny(IDictionary`2 context)
//        at FluentAssertions.Execution.AssertionScope.Dispose()
//        at FluentAssertions.Equivalency.EquivalencyValidator.AssertEquality(Comparands comparands, EquivalencyValidationContext context)
//        at FluentAssertions.Collections.GenericCollectionAssertions`3.BeEquivalentTo[TExpectation](IEnumerable`1 expectation, Func`2 config, String because, Object[] becauseArgs)

dto.Should().BeEquivalentTo(entity, c => c
        .WithMapping<EntityDto>(s => s.EntityId, d => d.Id)
        .WithTracing());

//    FluentAssertions.Execution.AssertionFailedException: Expected property dto.Id to be 1, but found 0.

//    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
//    - FluentAssertions.Equivalency.Matching.MappedPathMatchingRule
//    - Match member by name (or throw)
//    - Be strict about the order of items in byte arrays
//    - Without automatic conversion.
//   
//    With trace:
//      dto
//      {
//          property dto.Id
//          {
//              Treating property dto.Id as a value type because System.Int32 overrides Equals.
//                  Equivalency was proven by ValueTypeEquivalencyStep
//          }
//          property dto.Name
//          {
//              Equivalency was proven by ReferenceEqualityEquivalencyStep
//          }
//          Equivalency was proven by StructuralEqualityEquivalencyStep
//      }
//   
//      at FluentAssertions.Execution.FallbackTestFramework.Throw(String message)
//      at FluentAssertions.Execution.TestFrameworkProvider.Throw(String message)
//      at FluentAssertions.Execution.CollectingAssertionStrategy.ThrowIfAny(IDictionary`2 context)
//      at FluentAssertions.Execution.AssertionScope.Dispose()
//      at FluentAssertions.Equivalency.EquivalencyValidator.AssertEquality(Comparands comparands, EquivalencyValidationContext context)
//      at FluentAssertions.Primitives.ObjectAssertions`2.BeEquivalentTo[TExpectation](TExpectation expectation, Func`2 config, String because, Object[] becauseArgs)


public class Entity
{
    public int EntityId { get; set; }
    public string Name { get; set; }
}

public class EntityDto 
{
    public int Id { get; set; }
    public string Name { get; set; }

    public static EntityDto MapFromEntity(Entity entity)
    {
        return new EntityDto()
        {
            Name = entity.Name
        };
    }
}

Expected behavior:

I would expect the same behavior using WithMapping over a collection as I would with a single object

Actual behavior:

FluentAssertions does not map the property. If you use ExcludingMissingMembers then the collection assertion incorrectly passes.

Versions

Fluent Assertions 6.5.1
dotnet version 6.0.102

Additional Information

possible related issue #1838

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants