NUnit 3 - TestCase即使它们“相等”也不验证ExpectedResult

时间:2016-09-14 16:02:09

标签: .net nunit

我试着查看已经回答的问题,但我的案子听起来都不熟悉,所以我打开了这个帖子。

我在VS 2015下使用NUnit 3,在对项目进行单元测试后,我意识到出了问题。事实上,预期结果与我期望收到的内容相同(不是参考,而是按价值),但NUnit没有对其进行验证。

是意志吗?

在代码下面运行测试。

public static class DataFactory
{
    public static class Dummy
    {
        public static string ContractUrl = "";

        public static IEnumerable Objects
        {
            get
            {
                yield return new TestCaseData(ContractUrl, true, false).Returns(false);
                yield return new TestCaseData(ContractUrl, "", "Ciao").Returns("Ciao");
                yield return new TestCaseData(ContractUrl, Payload.Dummy.TrueRequest, Payload.Dummy.TrueResponse).Returns(Payload.Dummy.TrueResponse);
            }
        }
    }
}

public static class Payload
{
    public static class Dummy
    {
        public static GetItemsRequest TrueRequest
        {
            get
            {
                return new GetItemsRequest() { };
            }
        }

        public static GetItemsResponse TrueResponse
        {
            get
            {
                return new GetItemsResponse()
                {
                    Result = true
                };
            }
        }
    }
}


[DataContract]
public class GetItemsRequest : ICloneable<GetItemsRequest>
{
    [DataMember]
    public string QuoteCode { get; set; }

    [DataMember]
    public int QuoteRevision { get; set; }

    [DataMember]
    public DocumentFormat Format { get; set; }

    [DataMember]
    [Description("Nel caso sia False devo inizializzare l'ambiente, ovvero scaricare tutti i documenti in tutte le lingue." +
                 "Viene pilotato dal CRM, che setta a False o True la property nel Request Payload.")]
    public bool GetContent { get; set; }

    [DataMember]
    [Description("Viene usato per indicare se nel GetContent deve essere passato il percorso del documento "+
                 "(GetRemotePath = true) oppure il contenuto del documento.")]
    public bool GetRemotePath { get; set; }

    //Language Code
    [DataMember]
    public string Language { get; set; }

    [DataMember]
    public List<Product> Products { get; set; }

    [System.Diagnostics.DebuggerStepThrough]
    public GetItemsRequest Clone()
    {
        return (GetItemsRequest)Cloning.DeepCopy(this);
    }
}


[DataContract]
public class Product
{
    [DataMember]
    public string ProductCode { get; set; }

    [DataMember]
    public string PositionCode { get; set; }
}

[DataContract]
public class GetItemsResponse
{
    [DataMember]
    public bool Result { get; set; }

    [Description("Messaggio d'errore. Si presenta solo se Result = false.")]
    [DataMember]
    public string Message { get; set; }

    [DataMember]
    public List<TDSContent> Contents { get; set; }
}

[DataContract]
public class TDSContent : Product
{
    [DataMember]
    public string Language { get; set; }

    [DataMember]
    public string TextContent { get; set; }
}

单元测试

    [Test]
    [TestCaseSource(typeof(DataFactory.Dummy), "Objects")]
    public object Dummy(string contractUrl, object payload, object expectedResult)
    {
        return expectedResult;
    }

其中给出了以下结果:

enter image description here

这是预期的行为吗? 预期结果是否必须与引用匹配而不是值?

2 个答案:

答案 0 :(得分:3)

这仅与参考相等性间接相关。正如您将注意到false的情况,测试对于值对象非常有效。

NUnit使用EqualConstraint将返回的结果与预期结果进行比较。因此,除非它们也可以在您自己的代码中使用Assert.AreEqual,否则不会进行比较。

在这种情况下,您没有覆盖类的Equals方法。因此,使用基础object.Equals方法。引用平等的地方,因为object实现的是什么。

答案 1 :(得分:0)

由于您正在与NUnit一无所知的类型进行比较,GetItemsRequest,最终它只是调用该类的Equals方法(它继承自{{1} }})。 According to MSDN,如果你没有在你的类中覆盖它,那么它将使用类的引用相等性和值类型稍微复杂的方式。

让我们深入了解NUnit的内容来验证这一点。向下objectyou'll see this code

TestMethodCommand.Execute()

这是最终调用您的测试方法的代码(在public override TestResult Execute(TestExecutionContext context) { // TODO: Decide if we should handle exceptions here object result = RunTestMethod(context); if (testMethod.HasExpectedResult) NUnit.Framework.Assert.AreEqual(testMethod.ExpectedResult, result); context.CurrentResult.SetResult(ResultState.Success); // TODO: Set assert count here? //context.CurrentResult.AssertCount = context.AssertCount; return context.CurrentResult; } 内)。如您所见,它接受您方法的返回值并将其传递给RunTestMethod。这个断言looks like this

Assert.AreEqual()

Is.EqualTo只需创建一个public static void AreEqual(object expected, object actual) { Assert.That(actual, Is.EqualTo(expected), null, null); } ,其Apply method looks like this

EqualConstraint

默认情况下public override ConstraintResult ApplyTo<TActual>(TActual actual) { AdjustArgumentIfNeeded(ref actual); return new EqualConstraintResult(this, actual, _comparer.AreEqual(_expected, actual, ref _tolerance)); } 引用(因为您没有指定不同的引用,因此它会在您的情况下)是_comparer,以及AreEqual method looks like this的相关部分}:

NUnitEqualityComparer

最后一行是实际比较的地方。