Reputation: 483
Mock Framework: Moq
Test Framework: NUnit
I feel like there's a simple answer to this and I'm just overlooking it, but I can't for the life of me figure out why this is giving me grief.
I have two mocks here, and I'm trying to verify that the unit under test is setting one mock's property to the other mock's property, as such:
[TestFixture]
public class Testmock
{
protected Mock<IOne> mockOne;
protected Mock<ITwo> mockTwo;
protected Controller UnitUnderTest;
[SetUp]
public void Setup()
{
mockOne = new Mock<IOne>();
mockTwo = new Mock<ITwo>();
UnitUnderTest = new Controller(mockOne.Object, mockTwo.Object);
}
[Test]
public void Test1()
{
string testString = "test";
mockOne.SetupGet(o => o.Val).Returns(testString);
UnitUnderTest.CopyVal();
mockTwo.VerifySet(t => t.Val = mockOne.Object.Val);
}
}
public interface IOne
{
string Val { get; set; }
}
public interface ITwo
{
string Val { get; set; }
}
public class Controller
{
IOne one;
ITwo two;
public Controller(IOne one, ITwo two)
{
this.one = one;
this.two = two;
}
public void CopyVal()
{
two.Val = one.Val;
}
}
When I run this test, it returns an error at VerifySet
that says:
Expected invocation on the mock at least once, but was never performed: t => t.Val = (String)null
But underneath that, says:
Performed invocations: ITwo.Val = "test"
So I know for certain that ITwo.Val
is getting set with IOne.Val
in my Controller
, but I must be setting up the mock wrong here for the VerifySet. I can replace the VerifySet with the string directly, e.g.:
mockTwo.VerifySet(t => t.Val = testString);
and the test will pass. Since mockOne.Object.Val
is SetupGet
to return testString
, I don't quite understand why I can't use mockOne.Object.Val
in place of testString
in the VerifySet
.
Upvotes: 0
Views: 357
Reputation: 274
I am not sure why mockOne.Object.Val returns null in the context of VerifySet. I believe it has something to do with Moq internal implementation (digging Moq sources can reveal the reason for such behavior).
However I can tell you how to change your test to make it work without using testString variable in VerifySet(). You should use It.Is(x => x == mockOne.Object.Val) instead of referring the mock property directly. Please see below:
[Test]
public void Test1()
{
string testString = "test";
mockOne.SetupGet(o => o.Val).Returns(testString);
UnitUnderTest.CopyVal();
mockTwo.VerifySet(t => t.Val = It.Is<string>(x => x == mockOne.Object.Val));
}
Hope this helps.
Upvotes: 1