C# – Verifying a method was called

cmockingmoqnetverify

Using Moq, I have a very odd issue where the setup on a mock only seems to work if the method I am setting up is public. I don't know if this is a Moq bug or if I just have this wrong (newbie to Moq). Here is the test case:

public class TestClass
{
    public string Say()
    {
        return Hello();
    }

    internal virtual string Hello()
    {
        return "";
    }
}

[TestMethod]
public void Say_WhenPublic_CallsHello()
{
    Mock<TestClass> mock = new Mock<TestClass>();
    mock.Setup(x => x.Hello()).Returns("Hello World");

    string result = mock.Object.Say();
    mock.Verify(x => x.Hello(), Times.Exactly(1));
    Assert.AreEqual("Hello World", result);     
}

Which fails with this message:

Say_WhenPublic_CallsHello failed: Moq.MockException:
Invocation was not performed on the mock 1 times: x => x.Hello()
at Moq.Mock.ThrowVerifyException(IProxyCall expected, Expression expression, Times times)…

If I make the Hello method public like this, the test passes. What is the issue here?

public virtual string Hello()
{
    return "";
}

Thanks in advance!

Best Answer

The test fails when Hello() is internal because Moq cannot provide an override of the method in this case. This means that the internal implementation of Hello() will run, rather than mock's version, causing the Verify() to fail.

Incidentally, what you are doing here makes no sense in the context of a unit test. A unit test should not care that Say() calls an internal Hello() method. This is implementation internal to your assembly and not a concern of consuming code.