如何防止代码重复

本文关键字:代码 何防止 | 更新日期: 2023-09-27 18:36:50

我正在尝试单元测试最佳实践,但我遇到了一个我无法解决的问题。生产代码有一个函数,可以将给定对象转换为另一个对象,如下所示:

原始对象:

public OriginalObject
{
    public string Id {get; set;}
    public string Value {get; set;}
    public int FormCode {get; set;}
    public int NameCode {get; set;}
    //other properties
}
public TransformedObject
{
    public string Value {get; set;}
    public int FormCode {get; set;}
    //other properties
}

变换功能:

public TransformedObject Transform(OriginalObject originalObject)
{
    var TransformedObject = new TransformedObject();
    TransformedObject.Value = originalObject.Value;
    TransformedObject.FormCode = originalObject.FormCode;
    return TransformedObject;
}

测试看起来像这样:

[Test]
public void Transform_NonNullOptionObject_ValuePropertyIsTheSame()
{
    OptionObjectTransform transform = InitTransform();
    CustomOptionObject result = transform.Transform(optionObject);//mock optionObject
    Assert.AreEqual(optionObject.Value, result.Value);
}

所以我的问题是我必须为每个属性编写一个测试吗? 或者有没有办法使用[TestCase]传入我要测试的属性? 还是应该检查是否所有属性都相等?我不认为最后一个是解决方案,因为如果测试失败,那么我们将不知道哪个属性不匹配。

如何防止代码重复

NUnit(和所有其他 xUnit 框架)的一个限制是它们在第一个断言失败时失败,并且不运行其他断言。正如您所说,这意味着如果尝试通过许多断言测试许多值,则无法检测到多个故障。

但是,正如您还确定的那样,许多重复测试(每个测试测试不同的值)也不理想,因为它涉及大量重复的代码,只是为了解决 NUnit 的限制。

"两全其美"的解决方案是测试对象数组的相等性。这可以采取以下形式:

[Test]
public void Transform_NonNullOptionObject_ValuePropertyIsTheSame()
{
    OptionObjectTransform transform = InitTransform();
    CustomOptionObject result = transform.Transform(optionObject);
    var expected = new[] { optionObject.Value, optionObject.FormCode };
    var actual = new[] { result.Value, result.FormCode };
    Assert.AreEqual(expected, actual);
}

这样,您可以使用一个测试测试多个值,并且可以同时了解许多故障。

对于简单的映射(即计算映射很少的地方,或"if"),我使用 SharpTestEx,其中有一个很好的Satisfy断言,它报告所有错误的断言。

代码是这样的:

mapped.Satisfy( m =>
    m.Prop1 == source.SomeData + "zz" &&
    m.Prop2 == source.Prop2 ...
);