Moq - ordered settings (expectations)

I am new to Moq and cannot figure out how I order settings. 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 done 5 times (its retry logic if the update doesn't work). After the 5th time, I want to configure and expect it to succeed (no exception thrown):

 _orderRepository.Setup(r => r.Update(It.Is<Order>(a => ((int)a.OrderStatusReference.EntityKey.EntityKeyValues[0].Value) == 2))).AtMostOnce(); 

Unfortunately, he continues to use the first code sample and is never updated.

If I had not used the Throws method, then I can use the callback method, however it cannot be used after the throw: (.

If there is a way or is this a limitation of Moq?

+4
source share
3 answers

Moq does not support ordering expectations. See here for more details.

Although I'm currently using Moq, I used to use RhinoMocks before, and of course it has some features that I sometimes overlook with the expected Moq expectations - one of them.

+1
source

Bach ... there are ways!

You can use the queue to return a list of return values ​​(the strategy here is pretty well explained: http://haacked.com/archive/2009/09/29/moq-sequences.aspx ).

Here is an example from this blog:

If you want this to work (which is not the case):

 reader.Setup(r => r.Read()).Returns(true); reader.Setup(r => r.Read()).Returns(true); reader.Setup(r => r.Read()).Returns(false); 

Just do it 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 it!

+15
source

I needed the same thing too, and I ended up writing this extension method that 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 an example of use:

 someMock.Setup(o => o.AMethodWithReturnTypeInt()).Returns(1, 2, 3, 4); 

For this example, if you name a shrouded method - for example, 6 times, it will return 1, 2, 3, 4, 1, 2, respectively.

Hope this helps ...

+2
source

All Articles