Reputation: 1071
I am mocking out a wrapper we use for some enterprise library calls. All was well in the world, my tests passed and the actual code worked!
However I then extended the functionality, and verified the tests all still passed. Bingo - they did. However they didn't in the real world because there is an expectation that
InitialiseDBCommand(string, commandtype)
will be called before
AddCmdParameter(string, dbtype, object)
So like a good boy, the first thing I want to do is write a test that exhibits this behavior and expects an exception to be thrown.
What I need is to rig up AddCmmParater to throw an exception IF InitialDBCommand has not been called with any string.
I figure I could do this with a call back, but it feels like moq'ing a method call sequence (not a method return sequence) ought to be there.
Something like
iDataAccessHelper.Setup(s=>s.AddCmdOutputParameter(It.IsAny<string>(),
It.IsAny<DbType>(),
It.IsAny<int>()))
.When(w=>w.InitialiseDBCommand(etc etc)
.Throws<NullReferenceException>()
Any pointers?
Upvotes: 3
Views: 4057
Reputation: 1959
There is a library that extends Moq to add this functionality called Moq Sequences. Which from their examples looks like
using (Sequence.Create())
{
mock.Setup(_ => _.Method1()).InSequence();
mock.Setup(_ => _.Method2()).InSequence(Times.AtMostOnce());
...
// Logic that triggers the above method calls should be done here.
...
}";
It asserts that Method1 is called before Method2
Upvotes: 3
Reputation: 15138
Well if you simply want to test if 2 methods are called in the correct order, one way to do it would be to add a counter that is incremented each time one of the methods is called and then check if it's the correct number. Here is one answer that describes it. Here is how I'd write it for your scenario:
[Test]
public void TestingCallOrder() {
int counter = 0;
var mockDataAccessStuff = new Mock<IDataAccessStuff>();
mockDataAccessStuff.Setup(x => x.AddCmdParameter(It.IsAny<string>())).Callback(() => {
Assert.AreEqual(counter, 0);
counter++;
});
mockDataAccessStuff.Setup(x => x.InitialiseDbCommand(It.IsAny<string>())).Callback(() => {
Assert.AreEqual(counter, 1);
counter++;
});
// more of the same
var myClass = new ClassThatImTesting(mockDataAccessStuff.Object);
myClass.DoWork();
// make sure both methods are called at least once ...
mockDataAccessStuff.Verify(x => x.AddCmdParameter(It.IsAny<string>()), Times.Once());
mockDataAccessStuff.Verify(x => x.InitialiseDbCommand(It.IsAny<string>()), Times.Once());
}
I think that's a very clean and readable way to write the test.
Upvotes: 3