我正在编写单元测试并考虑实现IClonable
的类型的场景。
所以当然我希望有一个测试Clone()
方法的单元测试。
[Test]
public void CloneObject()
{
MyType original = new MyType();
MyType clone = (MyType)original.Clone();
// Assert for equality
}
所以我的第一个任务就是让Assert
获得平等。我看到以下选项:
MyType
的所有属性(字段)并逐一检查Equals()
中覆盖MyType
,让MyType
说两个实例是否相等(考虑到有时候测试的相等性被视为生产代码的相等)MyType
必须是[Serializable]
,但如果它具有例如接口属性,则有时很难做到)对于前两个我可以设置我的测试并且它们运行良好。但是如果我更改MyType
并添加其他属性怎么办?如果Clone()
没有复制这个并且我没有将它添加到checked属性列表或equals方法中,即使没有复制属性,我的测试仍会通过。
你如何解决这种测试?
答案 0 :(得分:5)
您可以使用FluentAssertions库(TDD必备,IMO),其中ShouldBeEquivalent
方法可以执行两个对象的graph comparison:
original.ShouldBeEquivalentTo(clone);
可以通过可选的options
参数自定义比较算法;有关详细信息,请参阅wiki。
为了使测试面向未来(即,当新属性添加到类中时它会中断,但不到Clone
方法),您可能希望测试克隆将其所有属性设置为随机非默认值的对象。 AutoFixture可以为您做到这一点。
// Arrange
var fixture = new Fixture();
var original = fixture.Create<MyType>();
// Act
var clone = original.Clone();
// Assert
clone.ShouldBeEquivalentTo(original);
有用的链接:
答案 1 :(得分:0)
我赞成实施Equals()。我认为没有理由为什么Equals()需要在生产和测试中产生不同的结果。
如果你不这样做,你的Assert可以调用object.ReferenceEquals(),如下所示:
Assert.IsTrue(object.ReferenceEquals(expectedObject, objectInHand));