I have used Rhino Mocks quite a bit in the past but recently starting using Moq. We were using an old version of the library (2.0) but when I switched to 4.0 I noticed a nice little detail.
Previously you would have to setup your tests in the AAA syntax, Arrange, Act, Assert. With the new syntax you can skip the Arrange and describe that in the Assert part of the test.
Let’s have a look. I’m going to assert that my homebrew Each extension will execute an action on all items in a collection.
public static class IEnumerableExtensions
{
public static void Each<T>(
this IEnumerable<T> target, Action<T> action)
{
foreach (var item in target)
{
action(item);
}
}
}
public interface IFakeEachOperator
{
void PerformSomeActionOn(int i);
}
Nothing fancy here, but have a look at the test:
[Test]
public void acation_is_called_on_Each_old_style()
{
//Arrange
var ints = new[] { 1, 2, 3, 4 };
var mock = new Mock<IFakeEachOperator>();
mock.Setup(s => s.PerformSomeActionOn(It.IsAny<int>()))
.AtMost(4);
<span style="color: green">//Act
</span>ints.Each(s => mock.Object.PerformSomeActionOn(s));
<span style="color: green">//Assert
</span>mock.Verify();
}
You’ll notice that I’m asserting against AtMost here; not very elegant as I’m looking for an exact match. In Moq 2.0 this was not possible (as far as I know), thus installed the latest and greatest and all of a sudden we are allowed to do this:
[Test]
public void acation_is_called_on_Each_new_style()
{
//Setup
var ints = new[] { 1, 2, 3, 4 };
var mock = new Mock<IFakeEachOperator>();
<span style="color: green">//Act
</span>ints.Each(s => mock.Object.PerformSomeActionOn(s));
<span style="color: green">//Arrange & Assert
</span>mock.Verify(s => s.PerformSomeActionOn(<span style="color: #2b91af">It</span>.IsAny<<span style="color: blue">int</span>>())
, <span style="color: #2b91af">Times</span>.Exactly(4));
}
I have replaced the first Arrange by Setup because that’s all it is really doing. The arrangement and assertion can now be combined and to me that makes for much better readability in the test.