Suppose I have a class MyClass, with a method MyMethod(), and I have a method under test which looks something like:
I would like to be able to write the test for this looking something like:
Of course I cannot do this, as the second Arrange simply replaces the first. I have to do:
which is OK, but the first pattern is a better reflection of the structure of the test and the method being tested, and is thus more readable.
Is there a syntax which allows me to say "arrange another call to this method" and so looks more like the first test and less like the second?
Dave
MethodUnderTest(MyClass myClass)
{
myClass.MyMethod();
// Do some other stuff
myClass.MyMethod();
}
I would like to be able to write the test for this looking something like:
[TestMethod]
public void MyTest()
{
MyClass mockMyClass = Mock.Create<
MyClass
>(Behaviour.Strict);
mockMyClass.Arrange(x=>x.MyMethod());
// Arrange the other stuff
mockMyClass.Arrange(x=>x.MyMethod());
MethodUnderTest(mockMyClass);
mockMyClass.AssertAll();
}
Of course I cannot do this, as the second Arrange simply replaces the first. I have to do:
[TestMethod]
public void MyTest()
{
MyClass mockMyClass = Mock.Create<
MyClass
>(Behaviour.Strict);
mockMyClass.Arrange(x=>x.MyMethod(), 2);
// Arrange the other stuff
MethodUnderTest(mockMyClass);
mockMyClass.AssertAll();
}
which is OK, but the first pattern is a better reflection of the structure of the test and the method being tested, and is thus more readable.
Is there a syntax which allows me to say "arrange another call to this method" and so looks more like the first test and less like the second?
Dave
8 Answers, 1 is accepted
0
Dave
Top achievements
Rank 1
answered on 16 Mar 2015, 06:03 PM
Of course, for
mockMyClass.Arrange(x=>x.MyMethod(), 2);
read
mockMyClass.Arrange(x=>x.MyMethod()).Occurs(2);
my error.
mockMyClass.Arrange(x=>x.MyMethod(), 2);
read
mockMyClass.Arrange(x=>x.MyMethod()).Occurs(2);
my error.
0
Hi Dave,
I think what you are looking for is asserting the order of execution. Here's the doc on that. Here's how it would apply to your test:
Regards,
Stefan
Telerik
I think what you are looking for is asserting the order of execution. Here's the doc on that. Here's how it would apply to your test:
mockMyClass.Arrange(x=>x.MyMethod()).InOrder();
// Arrange the other stuff, possibly again InOrder()
mockMyClass.Arrange(x=>x.MyMethod()).InOrder();
Regards,
Stefan
Telerik
Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.
0
Dave
Top achievements
Rank 1
answered on 20 Mar 2015, 08:57 AM
Thanks Stefan, but I can't get this to work. I have put together a small test project which you can download from http://www.knoware.co.uk/TestInOrderProblem.zip. I would be most grateful if you could have a look at it and tell me what I am doing wrong.
0
Accepted
Hi Dave,
I took a look at your tests and it seems what you need is not InOrder(), but InSequence().
Here's your preferred test, updated to work correctly:
Further information about sequential mocking can be found in the documentation.
Regards,
Stefan
Telerik
I took a look at your tests and it seems what you need is not InOrder(), but InSequence().
Here's your preferred test, updated to work correctly:
[TestMethod]
public
void
ThisIsWhatIWantToDo_ShouldWorkButDoesnt()
{
_classToBeMocked.Arrange(x => x.Method1()).InSequence().OccursOnce();
_classToBeMocked.Arrange(x => x.Method2()).OccursOnce();
_classToBeMocked.Arrange(x => x.Method3()).OccursOnce();
_classToBeMocked.Arrange(x => x.Method1()).InSequence().OccursOnce();
_classToBeTested.MethodToBeTested();
_classToBeMocked.AssertAll();
}
Further information about sequential mocking can be found in the documentation.
Regards,
Stefan
Telerik
See What's Next in App Development. Register for TelerikNEXT.
0
Dave
Top achievements
Rank 1
answered on 26 Mar 2015, 12:02 PM
Stefan
yes that works, thanks.
I am quite confused as to the difference between InSequence() and InOrder(). Could you briefly explain the difference, and when you would use InOrder().
Thanks
Dave
yes that works, thanks.
I am quite confused as to the difference between InSequence() and InOrder(). Could you briefly explain the difference, and when you would use InOrder().
Thanks
Dave
0
Hello Dave,
InSequence() allows you to specify different behavior, e.g. different return values, for successive calls to the same member, e.g.:
InOrder() allows you to assert the order of calls within a test. The assertion will fail if the arranged calls are executed out of the predefined order or not executed at all, e.g.:
Regards,
Stefan
Telerik
InSequence() allows you to specify different behavior, e.g. different return values, for successive calls to the same member, e.g.:
Mock.Arrange(() => DateTime.Now).Returns(DateTime.Now).InSequence();
Mock.Arrange(() => DateTime.Now).Returns(DateTime.Now.AddDays(1)).InSequence();
Mock.Arrange(() => db.BeginTransaction()).InOrder();
Mock.Arrange(() => db.EndTransaction()).InOrder();
Mock.Assert(db);
Regards,
Stefan
Telerik
See What's Next in App Development. Register for TelerikNEXT.
0
Dave
Top achievements
Rank 1
answered on 27 Mar 2015, 10:55 AM
Hmm. That was my understanding. However what my example is doing would seem to be exactly what InOrder (rather than InSequence) is used for. I guess it's just a matter of trying both and seeing which works in a given situation.
0
Hi Dave,
If you want to use InOrder() multiple times on the same member, you actually need to combine it with InSequence(), like so:
I'm sorry that I missed this detail in my previous post.
Regards,
Stefan
Telerik
If you want to use InOrder() multiple times on the same member, you actually need to combine it with InSequence(), like so:
mockMyClass.Arrange(x=>x.MyMethod()).InSequence().InOrder();
// Arrange the other stuff, possibly again InOrder()
mockMyClass.Arrange(x=>x.MyMethod()).InSequence().InOrder();
I'm sorry that I missed this detail in my previous post.
Regards,
Stefan
Telerik
See What's Next in App Development. Register for TelerikNEXT.