我试图理解为什么mocking以这种方式表现(我正在使用NUnit和Moq).比方说,我们有一个简单的类:
public class Package
{
public virtual int PackageId { get; set; }
public Package()
:this(-1)
{
}
public Package(int packageId)
{
PackageId = packageId;
}
}
Run Code Online (Sandbox Code Playgroud)
和一些简单的测试讨论:
[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);
}
}
Run Code Online (Sandbox Code Playgroud)
第一次测试失败,因为samplePackage.Object.PackageId返回-1,而不是预期的10.据我所知,mocked Package()调用参数化构造函数,它使用默认值-1初始化该属性.在第二次测试中,我们发现samplePackage.Object.PackageId返回0.
第一件事我不明白为什么返回0(在调试中我看到10在构造函数中传递,但属性保持为0值).第二个:如果我们samplePackage.SetupProperty(x => x.PackageId, SamplePackageId)在第二次测试中取消注释该命令,它将成功.那么为什么SetupProperty在这种情况下表现得如预期(属性返回10),而不是在第一次测试中这样做?
能否请你帮忙?这是我的第一篇文章,所以不要太严厉:)
virtual默认情况下,所有mockable()方法都使用代理,因此这就是您0在第二次测试中获得默认值()的原因(未设置代理).不过,您可以通过设置CallBase = true模拟来解决这个问题.
CallBase = true 将使用默认实现(如果可用)而不是尝试模拟所有内容.
我花了一秒钟才弄清楚第一个失败的原因,我认为这是因为SetupProperty只使用默认值打开跟踪,因为你在构造函数中覆盖了那个默认值,那么就是使用它.如果你想强制一个值,那么你需要使用Setup(x=>x.PackageId).Returns(SamplePackageId)或SetupGet