rhughes
rhughes

Reputation: 9583

Verifying in Sequence

I am trying to verify a set of method calls in sequence.

Here is a sample of what I would like to do. This test should fail, but it actually passes:

    public interface IMyInterface
    {
        void Method(int i);
    }

    public class MyClass : IMyInterface
    {
        public void Method(int i)
        {
        }
    }

    [TestMethod]
    public void MyTestMethod()
    {
        var mock = new Mock<IMyInterface>();

        var listOfThings = new List<int> { 5, 4, 3, 2, 1 };

        MethodUnderTest(mock.Object, listOfThings);

        mock.Verify(m => m.Method(1));
        mock.Verify(m => m.Method(2));
        mock.Verify(m => m.Method(3));
        mock.Verify(m => m.Method(4));
        mock.Verify(m => m.Method(5));
    }

    public void MethodUnderTest(IMyInterface myInterface, List<int> things)
    {
        foreach (var i in things)
        {
            myInterface.Method(i);
        }
    }

This should fail, as the Verify calls expect a different order of parameters.

I have tried MockSequence like this:

    [TestMethod]
    public void MyTestMethod()
    {
        var mock = new Mock<IMyInterface>();

        var listOfThings = new List<int> { 5, 4, 3, 2, 1 };

        var s = new MockSequence();

        mock.InSequence(s).Setup(m => m.Method(1));
        mock.InSequence(s).Setup(m => m.Method(2));
        mock.InSequence(s).Setup(m => m.Method(3));
        mock.InSequence(s).Setup(m => m.Method(4));
        mock.InSequence(s).Setup(m => m.Method(5));

        MethodUnderTest(mock.Object, listOfThings);

        mock.Verify(m => m.Method(1));
        mock.Verify(m => m.Method(2));
        mock.Verify(m => m.Method(3));
        mock.Verify(m => m.Method(4));
        mock.Verify(m => m.Method(5));
    }

But I guess I'm doing this wrong.

Using MockBehaviour.Strict doesn't seem to work either:

    [TestMethod]
    public void MyTestMethod()
    {
        var mock = new Mock<IMyInterface>(MockBehavior.Strict);

        var listOfThings = new List<int> { 5, 4, 3, 2, 1 };

        mock.Setup(m => m.Method(1));
        mock.Setup(m => m.Method(2));
        mock.Setup(m => m.Method(3));
        mock.Setup(m => m.Method(4));
        mock.Setup(m => m.Method(5));

        MethodUnderTest(mock.Object, listOfThings);

        mock.Verify(m => m.Method(1));
        mock.Verify(m => m.Method(2));
        mock.Verify(m => m.Method(3));
        mock.Verify(m => m.Method(4));
        mock.Verify(m => m.Method(5));
    }

I can't use a Setup to configure the parameters passed into the mock call, as these values do not come from a mockable source.

Upvotes: 3

Views: 3575

Answers (1)

Mel Gerats
Mel Gerats

Reputation: 2252

Creating your mock with MockBehavior.Strict

var mock = new Mock<IMyInterface>(MockBehavior.Strict);

will allow you to verify the calls are in sequence. The complete method would look like

[TestMethod]
public void MyTestMethod()
{
    var mock = new Mock<IMyInterface>(MockBehavior.Strict);

    //will fail
    var listOfThings = new List<int> { 5, 4, 3, 2, 1 };

    //will pass
    var listOfOtherThings = new List<int> { 1, 2, 3, 4, 5 };

    var s = new MockSequence();

    mock.InSequence(s).Setup(m => m.Method(1));
    mock.InSequence(s).Setup(m => m.Method(2));
    mock.InSequence(s).Setup(m => m.Method(3));
    mock.InSequence(s).Setup(m => m.Method(4));
    mock.InSequence(s).Setup(m => m.Method(5));

    MethodUnderTest(mock.Object, listOfThings);

    mock.Verify(m => m.Method(1));
    mock.Verify(m => m.Method(2));
    mock.Verify(m => m.Method(3));
    mock.Verify(m => m.Method(4));
    mock.Verify(m => m.Method(5));
}

Upvotes: 6

Related Questions