为 NUnits 结果提供相等性
Provide equality for NUnits results
我们有 Result
参数用于 NUnit 上的各种参数化测试。这适用于 .NET 中内置了相等性的简单类型。但是我想知道是否有办法验证测试方法 returns 一个复杂的对象:
[TestCase("MyValue", Result = new MyType(...) /* doesn't work as we can only use compile-time constants for attributes */]
public MyType Check(string value)
{
var target = ...
return target.DoSomething(value);
}
假设 target.DoSomething
returns 一个 MyType
的实例,测试应该确保返回的实例等于我在 TestCase
中提供的实例。由于 MyType
既不实现 IEquatable
也不覆盖 Equals
等式是使用 ReferenceEquals
确定的,这当然是错误的。此外,正如我在评论中提到的,我们无法在属性中创建 MyType
的实例,因为它不是编译时常量。
那么我们如何为我们的测试提供一个复杂的实例并检查结果是否等于那个?
我们可以为此使用 TestCaseSource
属性,它允许确定为测试用例提供更复杂用途的成员。因此我们也可以 return 任何类型的复杂实例。然而,正如已经提到的那样,我们不能依赖 TestCase
的 Result
标签,因为它隐含地将提供的实例与使用默认比较器 returned 的实例进行比较,后者使用 [=16] =].
所以我们不提供预期结果 Result
而是作为测试的简单参数,并提供我们自己的逻辑来判断什么是相等的:
[TestCaseSource("TestcaseMethod")]
public MyType Check(string value, MyType expected)
{
var target = ...
var actual = target.DoSomething(value);
bool retVal = // check the properties of actual towards those of expected
Assert.IsTrue(retVal);
}
public IEnumerable<object> TestcaseMethod()
{
yield return new object[] { "MyValue", new MyType(/* expected outcome */);
yield return new object[] { "AnotherValue", new MyType(/* expected outcome */);
}
哪里
public class MyType
{
// here come the actual values to be compared
}
编辑:在 Assert
语句中检查相等性的更直接的方法是使用 EqualConstraint
:
Assert.That(expected, Is.EqualTo(actual).Using(new MyComparer());
这将使用自定义比较器。
我们习惯用Fody Equals来比较自定义类 Equals,有一个nuget包可以安装它。为了使用它只是将 Equals 作为 header 装饰器,你应该能够正确地比较它
ExpectedResult 属性只是语法上的一点好处,在任何方面都不是必需的。您始终可以向该方法添加一个额外的参数,给出期望值,并在测试中以您喜欢的任何方式对其进行测试。
我们没有计划增强 NUnit 用来检查您的 ExpectedResult 的内部相等性比较。
我们有 Result
参数用于 NUnit 上的各种参数化测试。这适用于 .NET 中内置了相等性的简单类型。但是我想知道是否有办法验证测试方法 returns 一个复杂的对象:
[TestCase("MyValue", Result = new MyType(...) /* doesn't work as we can only use compile-time constants for attributes */]
public MyType Check(string value)
{
var target = ...
return target.DoSomething(value);
}
假设 target.DoSomething
returns 一个 MyType
的实例,测试应该确保返回的实例等于我在 TestCase
中提供的实例。由于 MyType
既不实现 IEquatable
也不覆盖 Equals
等式是使用 ReferenceEquals
确定的,这当然是错误的。此外,正如我在评论中提到的,我们无法在属性中创建 MyType
的实例,因为它不是编译时常量。
那么我们如何为我们的测试提供一个复杂的实例并检查结果是否等于那个?
我们可以为此使用 TestCaseSource
属性,它允许确定为测试用例提供更复杂用途的成员。因此我们也可以 return 任何类型的复杂实例。然而,正如已经提到的那样,我们不能依赖 TestCase
的 Result
标签,因为它隐含地将提供的实例与使用默认比较器 returned 的实例进行比较,后者使用 [=16] =].
所以我们不提供预期结果 Result
而是作为测试的简单参数,并提供我们自己的逻辑来判断什么是相等的:
[TestCaseSource("TestcaseMethod")]
public MyType Check(string value, MyType expected)
{
var target = ...
var actual = target.DoSomething(value);
bool retVal = // check the properties of actual towards those of expected
Assert.IsTrue(retVal);
}
public IEnumerable<object> TestcaseMethod()
{
yield return new object[] { "MyValue", new MyType(/* expected outcome */);
yield return new object[] { "AnotherValue", new MyType(/* expected outcome */);
}
哪里
public class MyType
{
// here come the actual values to be compared
}
编辑:在 Assert
语句中检查相等性的更直接的方法是使用 EqualConstraint
:
Assert.That(expected, Is.EqualTo(actual).Using(new MyComparer());
这将使用自定义比较器。
我们习惯用Fody Equals来比较自定义类 Equals,有一个nuget包可以安装它。为了使用它只是将 Equals 作为 header 装饰器,你应该能够正确地比较它
ExpectedResult 属性只是语法上的一点好处,在任何方面都不是必需的。您始终可以向该方法添加一个额外的参数,给出期望值,并在测试中以您喜欢的任何方式对其进行测试。
我们没有计划增强 NUnit 用来检查您的 ExpectedResult 的内部相等性比较。