C# – Moq verify method fails even though method will be called

cmockingmoqnetunit testing

I have some troubles using Moq. Following unit test throws an exception, even though the according method will be called.

[TestMethod]
public void CreateFinishTest() {
    // mock methods 
    factoryMock.Setup(f => f.LoadPlan("TestPlanDoNotUse")).Returns(testPlan).Verifiable();
    factoryMock.Setup(f => f.CreateFinish(It.IsAny<CreateFinishMessage>(), It.IsAny<string>())).Returns(testFinish.Id).Verifiable();

    try {
        var cfm = new CreateFinishMessage() {
            ClientId = 11,
            MessageId = 23456,
            CustomerId = 6,
            FinishName = "MyFinish",
            PlanId = "TestPlanDoNotUse"
        };
        var cmd = sysCfg.Executor.CreateFinish(cfm); // calls LoadPlan with cfm.PlanId and CreateFinish with cfm and cfm.PlanId
        sysCfg.Executor.Execute(cmd);

        factoryMock.Verify(f => f.LoadPlan("TestPlanDoNotUse"), Times.Exactly(1));
        factoryMock.Verify(f => f.CreateFinish(It.IsAny<CreateFinishMessage>(), It.IsAny<string>()), Times.Exactly(1));
    } catch (Exception exc) {
        Assert.Fail(exc.Message);
    }
}

This Error occurs:

Expected invocation on the mock exactly 1 times, but was 0 times: f => f.LoadPlan("TestPlanDoNotUse")

Configured setups:
f => f.LoadPlan("TestPlanDoNotUse"), Times.Once

Performed invocations:
IFactory.LoadPlan("TestPlanDoNotUse")
Factory.CreateFinish(IndiValue.LiveMarket.IndiCore.Communication.MessagingFormat.CreateFinishMessage, "MyFinish")

I've tried several different Verify-Calls but it won't work. And the Error which occurs seems quite confusing it's says that LoadPlan("TestPlanDoNotUse") is never called, but it's listed @ Performed invocations.

Problem solved:

I think i found the problem, it wasn't a Moq problem. In sysCfg.Executor.CreateFinish(cfm) a new thread was created and started. This thread wasn't finished and so factoryMock.Verify(...) failed.

I used AutoResetEvents:

// create AutoResetEvent triggers
AutoResetEvent m_testTrigger1 = new AutoResetEvent(false);

// mock methods     
factoryMock.Setup(f => f.LoadPlan(It.IsAny<string>())).Returns(testPlan).Callback(() => m_testTrigger1.Set());

// do something

// wait for triggers
bool didReturn1 = m_testTrigger1.WaitOne(timeOut);

Best Answer

On the Verifiable not being called, it's important that the arguments in your expectation match the arguments that are being used by the production code.

Regarding the use of Thread.Sleep, avoid it wherever possible as it will only slow down the tests to meet your slowest machine. I typically introduce WaitHandles into my tests to ensure that the tests run as fast as the code.

Take a peek here on a small utility that uses WaitHandles with events.