Darthg8r
Darthg8r

Reputation: 12675

Assert that 2 objects are equal

So, I have a layer in my application that maps one type of an object into another. Think ViewModel to model type of mapping. The ViewModel may have properties that are named differently or do not exist in the model. And vice-versa will be true as well.

I want to test my mapping layer, comparing the assignments, but also allowing me to provide some sort edge case handling for the properties that are different. Ideally, the test would fail if all of the properties in the ViewModel are not checked.

Does anyone know if such a beast exists already?

public class CustomerViewModel
{
     // This is the same as CustomerModel.CustomerName, but the names differ
     public string Name { get; set; }
     public int ID { get; set; }
}

public class CustomerModel
{
     public string CustomerName { get; set; }
     public int ID { get; set; }
}

// Would auto test the properties that match automatically.  Additionaltest test for non matching.  Fails if all properties aren't tested
Assert.CompareObjects(customerViewModelInstance, customerModelInstance)
     .AdditionalTest("Name", "CustomerName")
     .AdditionalComplexText((viewModel, model) =>
           {
                // do some sort of a compare of complex objects.  Maybe the viewmodel has address fields, address1, address2 while the Model has an Address object with those fields.
           });

The driving force behind this is the daunting task of having to assert every single property manually in code for a very large application.

Upvotes: 2

Views: 2469

Answers (1)

David L
David L

Reputation: 33815

You would need to override .Equals() so that it compared properties, then use the

Assert.AreEqual Method (Object, Object). Please see below:

Compare equality between two objects in NUnit

You would want to implement such a thing in your model itself.

// useful class
public class MyStuff 
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int MyValue { get; set; }

    public override int GetHashCode()
    {
        return Id;
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != typeof (MyStuff)) return false;

        var other = obj as MyStuff;

        return (other.Id == Id
            && other.MyValue == MyValue
            && other.Equals(other.Name, Name));
        // use .Equals() here to compare objects; == for Value types

        // alternative weak Equals() for value objects:
        // return (other.MyValue == MyValue && other.Equals(other.Name, Name) );
    }
}

EDIT: In retrospect, I have decided that having a duplication of properties in your viewmodel and model is probably a bad pattern and is part of the reason you are having so many testing issues. Rather, you should allow your ViewModel to wrap your model.

public class CustomerViewModel
{
    // This is the same as CustomerModel.CustomerName, but the names differ
    public CustomerModel CustomerModel { get; set; }

    pubiic CustomerViewModel()
    {
        CustomerModel = new CustomerModel();
    }
}

public class CustomerModel
{
     public string CustomerName { get; set; }
     public int ID { get; set; }
}

At that point it's much easier to test it since you have your wrapped model that you can compare to a new copy of the same model, using the .Equals override pattern. At the end of the day I just don't think that trying to come up with a magic bullet "compare any model to any model" is a good idea, nor is it practical.

Upvotes: 2

Related Questions