I must say I’m really a huge fan of Moq. Moq is steady growing and the developer community is quite impressive in inventing new features and extensions. I recently ran over a nice feature suggestion placed in a private branch from moq. The branch belongs to Brian J. Cardiff. I suggest you check also his blog out! The feature brain suggested is an extension method which allows to do sequential setups. The sequential setup allows to specify in a fluent way for example different return types on a mock for each call. Let’s have an example!
Assuming we have the following components:
public interface ITestInterface
{
int Count { get; }
T Get<T>() where T : IMyComparable;
}
public interface IMyComparable : IComparable<string> {}
public class MyComparable : IMyComparable {
private readonly string textToCompareAgainst;
public MyComparable(string text)
{
textToCompareAgainst = text;
}
public int CompareTo(string obj)
{
return this.textToCompareAgainst.CompareTo(obj);
}
}
With sequential setup we are now able to specify that each time the property Count or the method Get<T> is called something new is returned. Let’s say we want our mock to behave like the following:
- Get property Count returns 1
- Get property Count returns 2
- Get property Count returns 3
- Get property Count throws FormatException
This can be achieved with sequential setup similar to the following code:
[Test]
public void PropertyCallSequence()
{
var testee = new Mock<ITestInterface>();
testee.SetupSequentials(x => x.Count)
.Returns(1)
.Returns(2)
.Returns(3)
.Throws(new FormatException());
ITestInterface mock = testee.Object;
Assert.AreEqual(1, mock.Count);
Assert.AreEqual(2, mock.Count);
Assert.AreEqual(3, mock.Count);
Assert.Throws<FormatException>(() => { var result = mock.Count; });
}
or
- Method call to Get<IMyComparable> returns new MyComparable(“TEST”)
- Method call to Get<IMyComparable> returns new MyComparable(“TE”)
- Method call to Get<IMyComparable> returns new MyComparable(“TESTTT”)
- Method call to Get<IMyComparable> throws NullReferenceException
This can be achieved with sequential setup similar to the following code:
[Test]
public void GenericCallSequence()
{
var testee = new Mock<ITestInterface>();
testee.SetupSequentials(x => x.Get<IMyComparable>())
.Returns(new MyComparable("TEST"))
.Returns(new MyComparable("TE"))
.Returns(new MyComparable("TESTTT"))
.Throws(new NullReferenceException());
ITestInterface mock = testee.Object;
Assert.AreEqual(0, mock.Get<IMyComparable>().CompareTo("TEST"));
Assert.AreEqual(0, mock.Get<IMyComparable>().CompareTo("TE"));
Assert.AreEqual(0, mock.Get<IMyComparable>().CompareTo("TESTTT"));
Assert.Throws<NullReferenceException>(() => { var result = mock.Get<IMyComparable>(); });
}
Isn’t that a nice addition? I hope this will have it’s place in the next releases of the Moq library.