I am working on a unit test for a project and I cannot figure out how to get NSubstitute to work the way I would expect it to. The issue I am having is that the code I was to substitute is in a while loop and depending on what is returned from the substituted value determines if the loop continues.
What I would like to do is have Process() return a different result based on what is passed in. I have tried
api.Process(Arg.Is<IEnumerable<int>>(new[] {1,2,3}, Arg.Any<bool>()).Returns(new ProcessingResult(){Success = true, IdsNotProcessed = List<int>{30}});
but it does not seems to work as processingResult comes back null because NSubstitue is not matching the argument.
[Test]
public void TestTwoLoops()
{
var api = Substitute.For<IApi>();
api.Process(/*list containing 1,2,3*/, Arg.Any<bool>()).Returns(new ProcessingResult(){Success = true, IdsNotProcessed = List<int>{30}});
api.Process(/*list containing 30*/, Arg.Any<bool>()).Returns(new List<int>{});
var sut = new WidgetMaker(api);
sut.MakeWidget();
}
public class WidgetMaker
{
public WidgetMaker(IApi api)
{
_api = api;
}
public void MakeWidgets(IEnumerable<int> widgetIds)
{
var idsToProcess = widgetIds.ToList();
while(true)
{
if(!idsToProcess.Any())
{
berak;
}
var processingResult = _api.Process(idsToProcess, false);
if(processingResult.Success)
{
idsToProcess.Clear();
idsToProcess.AddRange(processingResult.IdsNotProcessed);
}
else
{
break;
}
}
}
private IApi _api;
}
As I was writing this question, the answer came to me, but I have a feeling others might find this helpful.
Using the overload that accepts a predicate and using the SequenceEqualExtension method with a parameter of new[] {/values I want to be input/}