简体   繁体   English

重写仅在C#中测试所需的Equals和GetHashcode方法的最佳位置

[英]Best place to override Equals and GetHashcode methods only required for testing in C#

I have the need to override Equals() and GetHashCode() so that I can compare two objects of the same class in my unit tests. 我需要重写Equals()GetHashCode()以便可以在单元测试中比较同一类的两个对象。

Suppose I have the class: MyClass in production that currently has no special requirement for the above methods to be overridden. 假设我有一个类:生产中的MyClass ,目前对于重写上述方法没有特殊要求。

However, in my tests I want to compare them using an overridden Equals . 但是,在测试中,我想使用overridden Equals比较它们。 Should I: 我是不是该:

  1. implement the methods directly in MyClass 直接在MyClass中实现方法

  2. create a derived class from MyClass that holds the overrides, then in my tests cast the instances of MyClass appropriately: 从保存覆盖的MyClass创建一个派生类,然后在我的测试中适当地投射MyClass的实例:

    // get instance of expected MyClass //获取预期的MyClass的实例
    // get instance of actual MyClass //获取实际MyClass的实例
    Assert.AreEqual((TestMyClass)expected, (TestMyClass)actual); Assert.AreEqual((TestMyClass)expected,(TestMyClass)actual);

I'm leaning towards option 2 as I think it keeps the production code cleaner. 我倾向于选择2,因为我认为它可以使生产代码更整洁。 It would also allow for a business logic specific override in the future directly on MyClass that might do it in different way from what I do in the tests if that makes sense. 它还将允许将来直接在MyClass上进行特定于业务逻辑的重写,如果MyClass ,这样做可能会与我在测试中所做的方式不同。

I guess the downside is that the tests and the test project are made more complex. 我想缺点是测试和测试项目变得更加复杂。

What is the preferred approach? 首选方法是什么?

I would suggest implementing IEqualityComparer<T> interface in your test project. 我建议在您的测试项目中实现IEqualityComparer<T>接口。 .NET also notices this interface for custom equality comparisons in some collection classes and LINQ. .NET还注意到此接口用于某些集合类和LINQ中的自定义相等性比较。

You have a thirth option, implement a custom assert where you preforms the equals logic you want. 您有一个选择,在自定义断言中执行所需的相等逻辑。

Option 1 adds code to your class which is not needed for your business logic, however it may add new bugs. 选项1将代码添加到您的类中,这对于您的业务逻辑是不需要的,但是它可能会添加新的错误。 Think about a linq operation, which uses a equal and hashcode. 考虑一下使用相等和哈希码的linq操作。 So your class will have a dirrent behavour. 因此,您的班级会有不良行为。 Option 2, is a lot of work. 选项2的工作量很大。 And you will have a maintance issue in your unit tests. 而且在单元测试中您将遇到维护问题。 Besides that you will test different class as your production code. 除此之外,您还将测试不同的类作为生产代码。 You may have perfectly working code under test, and not working code in production. 您可能正在测试的代码完全正常,而在生产环境中却没有代码。

I'd go for the derived TestMyClass option to keep the production code simpler. 我将使用派生的TestMyClass选项来简化生产代码。 However I don't believe you'd be able to cast your MyClass objects to TestMyClass objects, instead you'll most likely need to create new instances of TestMyClass with a constructor that takes a MyClass as a parameter 但是我不相信您能够将MyClass对象转换为TestMyClass对象,相反,您极有可能需要使用将MyClass作为参数的构造函数来创建TestMyClass的新实例。

创建一个扩展方法,并在测试项目中使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM