'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