I am fairly new to Moq and cant work out how I am to order setups. I have the following code:
_orderRepository.Setup(r => r.Update(It.Is<Order>(a => ((int)a.OrderStatusReference.EntityKey.EntityKeyValues[0].Value) == 2)))
.Throws(exception)
.AtMost(5);
I want this to be executed 5 times (its retry logic, if the update fails). After the 5th time I want to setup and expect that it is successful (An exception is not thrown):
_orderRepository.Setup(r => r.Update(It.Is<Order>(a => ((int)a.OrderStatusReference.EntityKey.EntityKeyValues[0].Value) == 2))).AtMostOnce();
Unfortinatly it continues to use the 1st code sample, and never successfully updates.
If I were not using the Throws method, then I can use the Callback method, however its not available after a throw :(.
If there a way or is this a limitation of Moq?
Bah... there are ways!
You can use a Queue to return a list of return values (strategy explained pretty well here: http://haacked.com/archive/2009/09/29/moq-sequences.aspx).
Here's a sample from that blog:
If you want this to work (which it doesn't):
reader.Setup(r => r.Read()).Returns(true);
reader.Setup(r => r.Read()).Returns(true);
reader.Setup(r => r.Read()).Returns(false);
Just do this instead:
Queue listOfOperations = new Queue<bool>(new bool[] { true, true, false });
reader.Setup(r => r.Read())
.Returns(() => listOfOperations.Dequeue());
Each time Read() is called a new value from your Queue will be used.
Enjoy!
I also needed the same thing and ended up with writing this extension method, which works for me:
public static class MoqExtensions {
public static void Returns<TMock,TResult>(this ISetup<TMock, TResult> source, params TResult[] results) where TMock : class {
int currentResultIndex = 0;
source.Returns (() => {
if(currentResultIndex >= results.Length) {
currentResultIndex = 0;
}
return results [currentResultIndex++];
});
}
}
And sample usage is:
someMock.Setup(o => o.AMethodWithReturnTypeInt()).Returns(1, 2, 3, 4);
For this sample, if you call the stubbed method -let's say- 6 times, it will return 1, 2, 3, 4, 1, 2 respectively.
Hope this helps...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With