Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为其结果提供平等_C#_Nunit_Equality - Fatal编程技术网

C# 为其结果提供平等

C# 为其结果提供平等,c#,nunit,equality,C#,Nunit,Equality,对于NUnit上的各种参数化测试,我们都有Result-参数。这对于在.NET中内置等式的简单类型非常有效。然而,我想知道是否有一种方法可以验证测试方法是否返回了一个复杂的对象: [TestCase("MyValue", Result = new MyType(...) /* doesn´t work as we can only use compile-time constants for attributes */] public MyType Check(string value) {

对于NUnit上的各种参数化测试,我们都有
Result
-参数。这对于在.NET中内置等式的简单类型非常有效。然而,我想知道是否有一种方法可以验证测试方法是否返回了一个复杂的对象:

[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
返回
MyType
的实例,测试应确保返回的实例与我在
TestCase
中提供的实例相同。由于
MyType
既不实现
IEquatable
也不重写
Equals
相等,因此使用
ReferenceEquals
确定相等,这当然是正确的。此外,正如我在评论中提到的,我们不能在属性中创建
MyType
的实例,因为它不是编译时常量


那么,我们如何为测试提供一个复杂的实例并检查结果是否与该实例相同呢?

我们可以使用
TestCaseSource
-属性来确定一个成员,该成员为测试用例提供更复杂的使用。因此,我们还可以返回任何类型的复杂实例。然而,正如allready提到的,我们不能依赖我们的
测试用例的
Result
-标记,因为它使用使用
ReferencEEquals
的默认比较器将提供的实例与返回的实例进行隐式比较

因此,我们不以
结果
的形式提供预期结果,而是作为测试的简单参数,并为条件相等的情况提供我们自己的逻辑:

[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 */);
}
编辑:检查
Assert
-语句中是否相等的更直接的方法是使用:


它将使用自定义比较器。

我们使用Fody Equals来比较自定义类,有一个nuget包来安装它。为了使用它只是将Equals作为标题装饰符,并且您应该能够正确地比较它

,ExpectedResult属性只是语法上的一点精确性,在任何方面都不是必需的。您总是可以向方法添加一个额外的参数,给出期望值,并在测试中以您喜欢的任何方式对其进行测试


我们没有计划增强NUnit用于检查预期结果的内部相等性比较。

例如,FluentAssertions库具有断言扩展方法
actual。应等效到(预期)
它将根据复杂类型的值对其进行比较-这将是一个很好的补充,它将期望属性出现在
MyType
上,以便测试它,这是我想要避免的。我更愿意在实际测试中应用这种逻辑。这是我在自己的答案中写的,但感谢你指出这不会有任何支持。事实上,当我发布我的答案时,你的答案(我想你自己回答)并不在我的面前。然而,现在来看,它声明NUnit使用ReferenceEquals获得预期结果。那是不对的。它使用的比较与您自己编写的EqualConstraint完全相同。在您的情况下,它将通过预期结果或代码中的直接断言使用ReferenceEquals。在其他情况下,对于以某种方式覆盖了平等的其他用户,它不会。因此它可以归结为相等-无论是通过使用
结果
-属性,在
断言
-语句中的
相等约束
-由
IEquatable
对象检查。相等
,或者-如果没有实现这些属性,则只检查
引用相等
(如果我没记错的话,这也是执行检查的正确顺序).@Himbrombeer简化了,但是是的。例如,数组相等在NUnit中定义为所有成员相等,顺序相同,等等。NUnit对相等有自己的理解,这是为了满足相等断言的需要。当您使用断言时,有一个钩子表示您要使用特定的比较器。这就是使用TestCase的ExpectedResult属性时不可能。
public class MyType
{
    // here come the actual values to be compared
}
Assert.That(expected, Is.EqualTo(actual).Using(new MyComparer());