31

At the moment I have:

    [Test]
    public void DrawDrawsAllScreensInTheReverseOrderOfTheStack() {
        // Arrange.
        var screenMockOne = new Mock<IScreen>();
        var screenMockTwo = new Mock<IScreen>();
        var screens = new List<IScreen>();
        screens.Add(screenMockOne.Object);
        screens.Add(screenMockTwo.Object);
        var stackOfScreensMock = new Mock<IScreenStack>();
        stackOfScreensMock.Setup(s => s.ToArray()).Returns(screens.ToArray());
        var screenManager = new ScreenManager(stackOfScreensMock.Object);
        // Act.
        screenManager.Draw(new Mock<GameTime>().Object);
        // Assert.
        screenMockOne.Verify(smo => smo.Draw(It.IsAny<GameTime>()), Times.Once(),
            "Draw was not called on screen mock one");
        screenMockTwo.Verify(smo => smo.Draw(It.IsAny<GameTime>()), Times.Once(), 
            "Draw was not called on screen mock two");
    }

But the order in which I draw my objects in the production code does not matter. I could do one first, or two it doesn't matter. However it should matter as the draw order is important.

How do you (using Moq) ensure methods are called in a certain order?

Edit

I got rid of that test. The draw method has been removed from my unit tests. I'll just have to manually test it works. The reversing of the order though was taken into a seperate test class where it was tested so it's not all bad.

Thanks for the link about the feature they are looking into. I sure hope it gets added soon, very handy.

Finglas
  • 15,518
  • 10
  • 56
  • 89

6 Answers6

33

I recently created Moq.Sequences which provides the ability to check ordering in Moq. You may want to read my post that describes the following:

  • Supports method invocations, property setters and getters.
  • Allows you to specify the number of times a specific call should be expected.
  • Provides loops which allow you to group calls into a recurring group.
  • Allows you to specify the the number of times a loop should be expected.
  • Calls that are expected to be called in sequence can be inter-mixed with calls that are expected in any order.
  • Multi-threaded support.

Typical usage looks like:

[Test]
public void Should_show_each_post_with_most_recent_first_using_sequences()
{
    var olderPost = new Post { DateTime = new DateTime(2010, 1, 1) };
    var newerPost = new Post { DateTime = new DateTime(2010, 1, 2) };
    var posts = new List<Post> { newerPost, olderPost };

    var mockView = new Mock<BlogView>();

    using (Sequence.Create())
    {
        mockView.Setup(v => v.ShowPost(newerPost)).InSequence();
        mockView.Setup(v => v.ShowPost(olderPost)).InSequence();

        new BlogPresenter(mockView.Object).Show(posts);
    }
}
Declan Whelan
  • 420
  • 5
  • 5
  • 2
    This is an awesome extension to Moq; for me lack of sequence support is the main omission in the project. IMO this should be pulled into the trunk (https://github.com/dwhelan/Moq-Sequences). – satnhak Dec 22 '11 at 12:45
  • 1
    what about performing invocation on different moq objects inside one sequence - is that supported? – chester89 May 04 '12 at 06:55
  • @chester89 Yes it is supported – ihebiheb Oct 27 '21 at 17:32
  • the [link](http://dpwhelan.com/blog/software-development/moq-sequences/) is broken – basecamp Dec 23 '22 at 06:28
18

A simple solution using Moq CallBacks:

    [TestMethod]
    public void CallInOrder()
    {
        // Arrange
        string callOrder = "";

        var service = new Mock<MyService>();
        service.Setup(p=>p.FirstCall()).Returns(0).CallBack(()=>callOrder += "1");
        service.Setup(p=>p.SecondCall()).Returns(0).CallBack(()=>callOrder += "2");

        var sut = new Client(service);

        // Act
        sut.DoStuff();

        // Assert
        Assert.AreEqual("12", callOrder);
    }
Owen Pauling
  • 11,349
  • 20
  • 53
  • 64
Kaj Bonfils
  • 416
  • 4
  • 10
5

It appears that it's not currently implemented. See Issue 24: MockSequence. This thread discusses the issue.

You might consider revising your tests, though. I generally feel that testing order leads to fragile tests, as it's often testing implementation details.

EDIT: I'm not sure that this addresses the OP's question. Lucero's answer may be more helpful.

TrueWill
  • 25,132
  • 10
  • 101
  • 150
  • 1
    Asserting/Verifying order may lead to fragile tests but NOT because it's testing implementation details. If you are using Mocks, especially with a class which uses the Inversion of Control (Dependency Injection) pattern, you are already testing implementation details; that is the point. I would say that testing order should not be a common pattern in your tests but there are valid cases where there are no alternatives to drive the correct code with TDD. – Jesse Webb Nov 02 '11 at 21:13
  • 1
    @JesseWebb - I think we're only disagreeing over semantics. Let's agree that some tests have inappropriate knowledge of internal implementation details. I prefer tests that will not break when the system under test is refactored, so long as the public API remains unchanged. As you say, there are cases for testing order, but they are not common. – TrueWill Nov 02 '11 at 21:49
  • The difference between the tests you are describing (are only concerned about the API of the system under test) and tests that use mocks is that the former can only be true unit tests if the class has no dependencies. If the class has any dependencies and you aren't using mocks, those are functional tests. I agree though that there is value in both black-box and white-box testing. – Jesse Webb Nov 03 '11 at 14:29
  • @JesseWebb - I don't feel this is the right forum for an extended discussion. I am speaking of unit testing in isolation while mocking dependencies. Interface dependencies are part of the public API. – TrueWill Nov 03 '11 at 14:35
  • In my case I want to test that the database has been connected to prior to service using the database. Whilst I am trying to test something that is an implementation detail it seems unlikely that my service using the database is ever going to be able to use the database without the connection being opened first. – Jack Hughes Sep 25 '13 at 12:21
2

Have a look at this blog post, it may solve your problem.

Lucero
  • 59,176
  • 9
  • 122
  • 152
  • Couldn't get this to work in my case, I couldn't use a queue in exchange of the array. Doesn't matter though now. See edit. – Finglas Nov 19 '09 at 19:52
1

Otherwise you could have used the Callback functions and increment/store a callIndex value.

slang
  • 626
  • 7
  • 26
Daniel
  • 8,133
  • 5
  • 36
  • 51
0

From the original post I could assume that the testing method do the following operations call:

var screenOne = new Screen(...);
var screenTwo = new Screen(...);
var screens = new []{screenOne, screenTwo};
var screenManager = new ScreenManager(screens);
screenManager.Draw();

Where 'Draw' method implementation is something like this:

public class ScreenManager
{
    public void Draw()
    {
        _screens[0].Draw();
        _screens[1].Draw();
    }
}

From my perspective, if the call order is very important then additional structure (that describe sequence) should be introduced into system.

The simplest implementation: each screen should know his subsequent element and call its Draw method after drawing himself:

// 1st version
public class Screen(Screen screenSubSequent)
{
    private Screen _screenNext;
    public Screen(Screen screenNext)
    {
        _screenNext=screenNext;
    }
    public void Draw()
    {
        // draw himself
        if ( _screenNext!=null ) _screenNext.Draw();
    }
}

public class ScreenManager
{
    public void Draw()
    {
        _screens[0].Draw();
    }
}

static void Main()
{
    var screenOne = new Screen(null, ...);
    var screenTwo = new Screen(screenOne, ...);
    var screens = new []{screenOne, screenTwo};
    var screenManager = new ScreenManager(screens);
}

From the one point, each Screen element should know a little about another one. This is not always good. If so: you can create some class like 'ScreenDrawer'. This object will store own screen and subsequent screen (probably inherit him from Screen class. Using other worlds: 'ScreenDrawer' class describes system structure. Here is a simplest scenario of implementation:

// 2nd version
public class ScreenDrawer
{
    private Screen _screenNext;
    public ScreenDrawer(Screen screenNext, ...) : base (...)
    {
        _screenNext=screenNext;
    }
    public void Draw()
    {
        // draw himself
        if ( _screenNext!=null ) _screenNext.Draw();
    }
}

public class ScreenManager
{
    public void Draw()
    {
        _screens[0].Draw();
    }
}

static void Main()
{
    var screenOne = new ScreenDrawer(null, ...);
    var screenTwo = new ScreenDrawer(screenOne, ...);
    var screens = new []{screenOne, screenTwo};
    var screenManager = new ScreenManager(screens);
}

2nd method introduce additional inheritance, but doesn't required Screen class to know about his subsequence element.

Summary: both methods do sub-sequential calls and doesn't require 'sequence' testing. Instead they require testing if current 'screen' calls another one and testing if 'ScreenManager' calls 'Draw' method of the 1st element in sequence.

This approach:

  1. More testable (can be implemented using most of testing framework without necessity to support 'sequence testing');
  2. More stable (nobody can easily change a sequence: hi will need not only update the source code, but also update few tests);
  3. More object oriented (you are working with object, not with abstract entities like 'sequence');
  4. As a result: much more supportable.

Thanks.

Budda
  • 18,015
  • 33
  • 124
  • 206