Reputation: 2314
I am trying to understand why mocking behaves in such a way (I'm using NUnit with Moq). Let's say, we have a simple class:
public class Package
{
public virtual int PackageId { get; set; }
public Package()
:this(-1)
{
}
public Package(int packageId)
{
PackageId = packageId;
}
}
And some simple tests to discuss:
[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);
}
}
The first test fails as samplePackage.Object.PackageId
returns -1, not 10 as expected. As I understand mocked Package()
calls parameterized constructor which initializes the property with default -1. In the second test we find samplePackage.Object.PackageId
returning 0.
The first thing I don't understand why 0 was returned (in debug I saw that 10 was passed in the constructor, but the property remained 0 value). The second one: if we uncomment this command samplePackage.SetupProperty(x => x.PackageId, SamplePackageId)
in the second test, it will succeed. So why SetupProperty
behaves as expected in that case (property returns 10), and not in such a way in the first test?
Could you please help? This is my first post so don't be severe :)
Upvotes: 2
Views: 300
Reputation: 67115
All mockable (virtual
) methods use a proxy by default, so that is why you get a default value (0
) on the second test (the proxy is not set). You can get around this by setting CallBase = true
on your mock, though.
CallBase = true
will use default implementations if available instead of trying to mock everything out.
It took me a second to figure out the reason for the first one failing and I believe that this is because SetupProperty
only turns on tracking with a default value and since you are overriding that default value in the constructor then that is what is used. If you want to force a value then you need to use Setup(x=>x.PackageId).Returns(SamplePackageId)
or SetupGet
Upvotes: 7