我试图理解为什么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),而不是在第一次测试中这样做?
答案 0 :(得分:7)
默认情况下,所有可模拟(virtual
)方法都使用代理,因此这就是您在第二次测试中获得默认值(0
)的原因(未设置代理)。不过,你可以通过在模拟上设置CallBase = true
来解决这个问题。
CallBase = true
将使用默认实现(如果可用),而不是尝试模拟所有内容。
我花了一秒时间才弄清楚第一个失败的原因,我认为这是因为SetupProperty
仅使用默认值启用跟踪,因为您在构造函数中覆盖了该默认值这是使用的。如果您想强制使用值,则需要使用Setup(x=>x.PackageId).Returns(SamplePackageId)
或SetupGet