NSubstitute – TestFixture 1在TestFixture 2中导致AmbiguousArgumentsException
我正在使用NUnit和NSubstitute编写C#unit testing。 我正在测试一个类,它将尝试从实现以下接口的配置提供程序中检索对象:
public interface IConfigProvider { T GetConfig(int id); T GetConfig(string id); }
正在测试的类只使用了GetConfig
的int版本,因此在SetUpFixture中我执行以下操作来设置一个总是返回相同虚拟对象的模拟配置提供程序:
IConfigProvider configProvider = Substitute.For<IConfigProvider>(); configProvider.GetConfig(Arg.Any()).Returns(new ConfigType(/* args */);
如果TestFixture是唯一运行的TestFixture,则运行绝对正常。 但是,在同一个程序集中的不同TestFixture中,我检查接收到的调用如下:
connection.Received(1).SetCallbacks(Arg.Any<Action>(), Arg.Any<Action>(), Arg.Any<Action>());
如果这些Received
测试在配置提供程序测试之前运行,则配置测试在SetUpFixture中失败并出现AmbiguousArgumentsException:
Here.Be.Namespace.ProfileManagerTests+Setup (TestFixtureSetUp): SetUp : NSubstitute.Exceptions.AmbiguousArgumentsException : Cannot determine argument specifications to use. Please use specifications for all arguments of the same type. at NSubstitute.Core.Arguments.NonParamsArgumentSpecificationFactory.Create(Object argument, IParameterInfo parameterInfo, ISuppliedArgumentSpecifications suppliedArgumentSpecifications) at System.Linq.Enumerable.d__7`2.MoveNext() at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) at NSubstitute.Core.Arguments.MixedArgumentSpecificationsFactory.Create(IList`1 argumentSpecs, Object[] arguments, IParameterInfo[] parameterInfos) at NSubstitute.Core.Arguments.ArgumentSpecificationsFactory.Create(IList`1 argumentSpecs, Object[] arguments, IParameterInfo[] parameterInfos, MatchArgs matchArgs) at NSubstitute.Core.CallSpecificationFactory.CreateFrom(ICall call, MatchArgs matchArgs) at NSubstitute.Routing.Handlers.RecordCallSpecificationHandler.Handle(ICall call) at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source, Func`2 predicate) at NSubstitute.Routing.Route.Handle(ICall call) at NSubstitute.Proxies.CastleDynamicProxy.CastleForwardingInterceptor.Intercept(IInvocation invocation) at Castle.DynamicProxy.AbstractInvocation.Proceed() at Castle.Proxies.IConfigProvider`1Proxy.GetConfig(Int32 id) at Here.Be.Namespace.ProfileManagerTests.Setup.DoSetup()
令我感到困惑的是,即使在测试运行之间我也能观察到这种效果 – 如果我使用NUnit GUI单独运行Received
测试,然后单独运行配置测试,配置测试将失败。 如果我再次立即运行配置测试,它们将通过。
我尝试过的事情:
碰巧,我正在使用的测试只会调用值为0或1的GetConfig
方法,所以我只能为这两个值提供Returns
规范而根本不使用匹配,但我想了解如何修复这更普遍。
不明确的论点是当NSubstitute将它正在使用的调用的参数与它所拥有的“参数匹配器”的堆栈进行比较时(每次调用Arg.Blah
,将参数匹配器添加到该堆栈中),它是无法解决哪个参数在哪里。
通常这是由于调用像blah(null, null)
,单个参数匹配器排队,但也可能是由于在调用配置之外使用arg匹配器而导致堆栈失去同步,或作为非虚方法的参数。
版本1.8.0(在您的问题之后发布)包括对后一种情况的略微改进的检测,因此可能值得尝试。
除此之外,我有几次这个问题,并使用了以下(痛苦)的方法。
有时问题可能是由于之前的夹具造成的,因此您可能需要锻炼以前的夹具并在那里进行探索。 ?
当我将Microsoft测试运行器切换到VSTest.Console
时,我遇到了类似的错误 (在MSTest.exe
下运行时没有发生MSTest.exe
)。
正如David在答案中所建议的那样,错误是由使用Arg.*
参数调用非替代方法引起的。 Arg.Any
被传递给实际的代码方法,在没有Returns
或Received
相关方法的情况下调用。
要扫描我的测试库以查找此类问题,我使用正则表达式搜索来查找带有Arg.
行Arg.
但不是Arg.
跟随Returns
或以Received
(?=^.*Arg.*$)(?=^((?!Arg.*.Returns).)*$)^((?!.Received(.*Arg.).)*$
它不是防弹filter(例如,它不排除多行语句),但它有助于减少检查的呼叫数量。
改变我的测试顺序。 不是很好的答案,但工作 – 尝试!
上述就是C#学习教程:NSubstitute – TestFixture 1在TestFixture 2中导致AmbiguousArgumentsException分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/957590.html