dimanche 29 novembre 2015

How to compared objects that have list of objects with Likeness?

I just started using the Likeness framework to help me with test-specific comparisons and so far I've been really impressed by it.

However, it doesn't seem to be able to compare objects that have list of other objects without having to explicitly state that I want the list comparison to occur.

Let me demonstrate:

First the classes I'll use:

public class ShoppingCart
{
    public Guid Id { get; set; }

    public List<Product> Products { get; set; }
}

public class Product
{
    public Guid Id { get; set; }

    public string Name { get; set; }

    public int Quantity { get; set; }
}

Now the actual test:

var firstCart = new ShoppingCart
    {
        Id = Guid.Empty,
        Products = new List<Product>
        {
            new Product
                {
                    Id = Guid.Empty,
                    Name = "ProductName",
                    Quantity = 1
                }
        }
    };

var expectedCart = new ShoppingCart
{
    Id = Guid.Empty,
    Products = new List<Product>
        {
            new Product
                {
                    Id = Guid.Empty,
                    Name = "ProductName",
                    Quantity = 1
                }
        }
}.AsSource().OfLikeness<ShoppingCart>();

expectedCart.ShouldEqual(firstCart);

The result is: The following members did not match: Products.

If I want it to work, I have to modify the likeness so that it becomes the following:

var expectedCart = new ShoppingCart
{
    Id = Guid.Empty,
    Products = new List<Product>
        {
            new Product
                {
                    Id = Guid.Empty,
                    Name = "ProductName",
                    Quantity = 1
                }
        }
}.AsSource()
.OfLikeness<ShoppingCart>()
.With(x => x.Products)
.EqualsWhen((src, desc) => src.Products
    .Select(p => p.AsSource()
    .OfLikeness<Product>())
    .SequenceEqual(desc.Products.Cast<object>()));

Now my problem is, I will have to write this exact code every time that two objects have lists of other objects in them, this will make the test harder to read. (I don't dare to think about how this would look with additional nesting)

How can I make it so that by default, Likeness will compare all lists using SequenceEqual?

Or maybe there's a re-usable way to do this so I don't to repeat the same code for every test for every type?

I really want to use this framework, but this is definitely causing some headaches on my side.

Aucun commentaire:

Enregistrer un commentaire