Reputation: 15709
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.
Upvotes: 31
Views: 19375
Reputation: 8368
Otherwise you could have used the Callback functions and increment/store a callIndex value.
Upvotes: 1
Reputation: 436
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);
}
Upvotes: 18
Reputation: 18343
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:
Thanks.
Upvotes: 0
Reputation: 440
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:
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);
}
}
Upvotes: 33
Reputation: 25523
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.
Upvotes: 5