visual-studiounit-testingmoqtest-explorer

Prevent long Visual Studio test trace output with Moq Verify


I wish to verify that a method has been called, using Moq's Verify method. Part of my test involves looping quite a large number of times, during which many other methods on my mock object, in addition to the one I want to verify, are called.

If the Verify assertion fails, in the Visual Studio Test Explorer output pane for the relevant test, in addition to the error message about the reason the verify fails, there is also listed every single other invocation that was made on the mock object, stretching into 1000s of lines. This makes the Test Explorer window become unusably laggy until the full exception detail has loaded, which can sometimes take minutes.

Is there any way to prevent Moq from listing all the other invocations that were performed? I only care about whether the Verify failed or not.

Contrived code to replicate the issue:

public interface IMyInterface
{
    void Foo();
    void Bar();
    void FooBar();
}

[TestClass]
public class TestClass1
{
    [TestMethod]
    public void TestMethod1()
    {
        using (var mock = AutoMock.GetLoose())
        {
            var myInterfaceMock = mock.Mock<IMyInterface>();
            var myInterfaceObj = myInterfaceMock.Object;

            for (var i = 0; i < 1000; i++)
            {
                myInterfaceObj.Foo();
                myInterfaceObj.Bar();
            }

            myInterfaceMock.Verify(x => x.FooBar(), Times.Once());
        }
    }
}

Test Explorer output, goes on for 1000s of lines (sorry for the large size, high DPI screen): enter image description here

Many thanks


Solution

  • This is not direct answer using Verify() but otherwise it prevents the Moq from listing all the other invocations that were performed.

    It uses Callback to count the number of times the method FooBarwas called. I don't know if you are gonna like this way?


    [TestMethod]
    public void TestMethod1()
    {
        int expectedCount = 1;
        int actualCount = 0;
        
        using (var mock = AutoMock.GetLoose())
        {
            var myInterfaceMock = mock.Mock<IMyInterface>();
            var myInterfaceObj = myInterfaceMock.Object;
            myInterfaceMock.Setup(mi => mi.FooBar()).Callback(() => actualCount++);
    
            for (var i = 0; i < 1000; i++)
            {
                myInterfaceObj.Foo();
                myInterfaceObj.Bar();
            }
    
            Assert.AreEqual( expectedCount, actualCount, $"Expected invocation on the mock was '{expectedCount}' times, but was called '{actualCount}' times");
        }
    }
    

    Output:

    Assert.AreEqual failed. Expected:<1>. Actual:<0>. Expected invocation on the mock was '1' times, but was called '0' times