用不同的构造函数模拟对象

时间:2013-12-11 21:29:01

标签: c# nunit moq

我试图理解为什么mocking以这种方式表现(我正在使用NUnit和Moq)。比方说,我们有一个简单的类:

public class Package
{
    public virtual int PackageId { get; set; }

    public Package()
        :this(-1)
    {
    }

    public Package(int packageId)
    {
        PackageId = packageId;
    }
}

和一些简单的测试讨论:

[TestFixture]
public class NUnitTrickyTest
{
    private const int SamplePackageId = 10;

    [Test]
    public void TestPackageSetUp_WhenMockedWithDefaultConstructor_ExpectSamplePackageIdSet()
    {
        var samplePackage = new Mock<Package>();

        samplePackage.SetupProperty(x => x.PackageId, SamplePackageId);

        Assert.AreEqual(SamplePackageId, samplePackage.Object.PackageId);
    }

    [Test]
    public void TestPackageSetUp_WhenMockedWithParametrizedConstructor_ExpectSamplePackageIdSet()
    {
        var samplePackage = new Mock<Package>(SamplePackageId);

        // samplePackage.SetupProperty(x => x.PackageId, SamplePackageId);

        Assert.AreEqual(SamplePackageId, samplePackage.Object.PackageId);
    }
}

第一次测试失败,因为samplePackage.Object.PackageId返回-1,而不是预期的10。据我所知,mock Package()调用参数化构造函数,该函数使用默认值-1初始化该属性。在第二个测试中,我们发现samplePackage.Object.PackageId返回0。

首先我不明白为什么返回0(在调试中我看到10在构造函数中传递,但属性保持为0值)。第二个:如果我们在第二个测试中取消注释此命令samplePackage.SetupProperty(x => x.PackageId, SamplePackageId),它将成功。那么为什么SetupProperty在这种情况下表现得像预期的那样(属性返回10),而不是在第一次测试中这样做?

你可以帮忙吗?这是我的第一篇文章,所以不要太严厉:)

1 个答案:

答案 0 :(得分:7)

默认情况下,所有可模拟(virtual)方法都使用代理,因此这就是您在第二次测试中获得默认值(0)的原因(未设置代理)。不过,你可以通过在模拟上设置CallBase = true来解决这个问题。

CallBase = true将使用默认实现(如果可用),而不是尝试模拟所有内容。

我花了一秒时间才弄清楚第一个失败的原因,我认为这是因为SetupProperty仅使用默认值启用跟踪,因为您在构造函数中覆盖了该默认值这是使用的。如果您想强制使用值,则需要使用Setup(x=>x.PackageId).Returns(SamplePackageId)SetupGet