'How can I configure Moq to return new instance per call?
I am trying to write a simple test with moq. When calling the mocked method for the second time, after changing the return value from the first call, the moq framework returns the modified object. I guess this is because I am changing the same reference.
How can I ensure that each call to the moq will return the same value?
public class VersionData
{
public int Number { get; set; }
public string Str { get; set; }
}
public interface ILogic
{
VersionData GetVersion();
}
[TestClass]
public class LogicTester
{
private Mock<ILogic> _mock;
[TestInitialize]
public void InitSingleTest()
{
_mock = new Mock<ILogic>();
}
[TestMethod]
public void Test()
{
_mock.Setup(x => x.GetVersion()).Returns(new VersionData { Number = 1, Str = "1" });
VersionData l1 = _mock.Object.GetVersion(); // OK
l1.Number = 2;
l1.Str = "2";
// Not OK - I'd expect l2.Number = 1 and l2.Str = "1" but l2.Number = 2 and l2.Str = "2"
VersionData l2 = _mock.Object.GetVersion();
return;
}
}
Solution 1:[1]
Your question is confusingly worded.
How can I ensure that each call to the moq will return the same value?
It suggests that you need the same value, instead, it should be "How can I configure Moq to return new instance per call?".
For that you have to use another overload of Returns
method which takes a Func<T>
as a parameter and pass a lambda. Your code as written configures the Moq to return the same instance for all calls made to GetVersion
method.
So your Test method becomes
[TestMethod]
public void Test()
{
_mock.Setup(x => x.GetVersion())
.Returns(() => new VersionData { Number = 1, Str = "1" });
VersionData l1 = _mock.Object.GetVersion(); // OK
l1.Number = 2;
l1.Str = "2";
VersionData l2 = _mock.Object.GetVersion();
Assert.AreNotSame(l1, l2);//True as mock returns new instance
}
Solution 2:[2]
You can do something like this
private static VersionData Get()
{
return new VersionData { Number = 1, Str = "1" };
}
Call the above method as
_mock.Setup(x => x.GetVersion()).Returns(Get());
VersionData l1 = _mock.Object.GetVersion(); // OK
l1.Number = 2;
l1.Str = "2";
VersionData l2 = _mock.Object.GetVersion().Returns(Get());
This would give you same result in all the cases
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Mark Seemann |