C# 在NSubstitue中使用IEnumerable设置参数匹配器

C# 在NSubstitue中使用IEnumerable设置参数匹配器,c#,ienumerable,nsubstitute,argument-matching,C#,Ienumerable,Nsubstitute,Argument Matching,我正在为一个项目进行单元测试,我不知道如何让NSubstitute以我期望的方式工作。我遇到的问题是,我要替换的代码位于while循环中,并且取决于被替换值返回的内容来确定循环是否继续 我想做的是让Process()根据传入的内容返回不同的结果。我试过了 api.Process(Arg.Is<IEnumerable<int>>(new[] {1,2,3}, Arg.Any<bool>()).Returns(new ProcessingResult(){Succ

我正在为一个项目进行单元测试,我不知道如何让NSubstitute以我期望的方式工作。我遇到的问题是,我要替换的代码位于while循环中,并且取决于被替换值返回的内容来确定循环是否继续

我想做的是让Process()根据传入的内容返回不同的结果。我试过了

api.Process(Arg.Is<IEnumerable<int>>(new[] {1,2,3}, Arg.Any<bool>()).Returns(new ProcessingResult(){Success = true, IdsNotProcessed = List<int>{30}});
api.Process(Arg.Is(new[]{1,2,3},Arg.Any()).Returns(new ProcessingResult(){Success=true,IdsNotProcessed=List{30});
但它似乎不起作用,因为processingResult返回null,因为NSubstitue与参数不匹配

    [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;
    }
[测试]
公共void testtwoops()
{
var api=替换为();
api.Process(/*list包含1,2,3*/,Arg.Any()).Returns(new ProcessingResult(){Success=true,IdsNotProcessed=list{30});
进程(/*列表包含30*/,Arg.Any())。返回(新列表{});
var sut=新WidgetMaker(api);
sut.MakeWidget();
}
公共类WidgetMaker
{
公共WidgetMaker(IApi api)
{
_api=api;
}
公共void MakeWidgets(IEnumerable WidgetId)
{
var idsToProcess=widgetIds.ToList();
while(true)
{
如果(!idspnProcess.Any())
{
柏拉克;
}
var processingResult=_api.Process(idsToProcess,false);
if(processingResult.Success)
{
idsToProcess.Clear();
idsToProcess.AddRange(processingResult.IdsNotProcessed);
}
其他的
{
打破
}
}
}
私人IApi_api;
}

当我写这个问题时,我想到了答案,但我感觉其他人可能会觉得这很有帮助

使用接受谓词的重载并使用SequenceEqualExtension方法和参数new[]{/values I want to be input/}

api.Process(Arg.Is(x=>x.SequenceEqual(new[]{1,2,3},Arg.Any())).Returns(new ProcessingResult(){Success=true,IdsNotProcessed=List{30});

当我写这个问题时,我想到了答案,但我感觉其他人可能会觉得这很有帮助

使用接受谓词的重载并使用SequenceEqualExtension方法和参数new[]{/values I want to be input/}

api.Process(Arg.Is(x=>x.SequenceEqual(new[]{1,2,3},Arg.Any())).Returns(new ProcessingResult(){Success=true,IdsNotProcessed=List{30});
api.Process(Arg.Is<IEnumerable<int>>(x => x.SequenceEqual(new[] {1,2,3}, Arg.Any<bool>())).Returns(new ProcessingResult(){Success = true, IdsNotProcessed = List<int>{30}});