Я предпочитаю не переопределять Equals только для того, чтобы включить тестирование. Не забывайте, что если вы переопределяете Equals, вам действительно следует переопределить GetHashCode, иначе вы можете получить неожиданные результаты, если, например, используете свои объекты в словаре.
Мне нравится подход, основанный на отражении выше, поскольку он учитывает добавление свойств в будущем.
Однако для быстрого и простого решения зачастую проще либо создать вспомогательный метод, который проверяет, равны ли объекты, либо реализовать IEqualityComparer в классе, который вы оставляете закрытым для своих тестов. При использовании решения IEqualityComparer вам не нужно беспокоиться о реализации GetHashCode. Например:
// Sample class. This would be in your main assembly.
class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
// Unit tests
[TestFixture]
public class PersonTests
{
private class PersonComparer : IEqualityComparer<Person>
{
public bool Equals(Person x, Person y)
{
if (x == null && y == null)
{
return true;
}
if (x == null || y == null)
{
return false;
}
return (x.Name == y.Name) && (x.Age == y.Age);
}
public int GetHashCode(Person obj)
{
throw new NotImplementedException();
}
}
[Test]
public void Test_PersonComparer()
{
Person p1 = new Person { Name = "Tom", Age = 20 }; // Control data
Person p2 = new Person { Name = "Tom", Age = 20 }; // Same as control
Person p3 = new Person { Name = "Tom", Age = 30 }; // Different age
Person p4 = new Person { Name = "Bob", Age = 20 }; // Different name.
Assert.IsTrue(new PersonComparer().Equals(p1, p2), "People have same values");
Assert.IsFalse(new PersonComparer().Equals(p1, p3), "People have different ages.");
Assert.IsFalse(new PersonComparer().Equals(p1, p4), "People have different names.");
}
}