Reputation: 4470
NSubstitute is complaining that my arguments are ambiguous, however as far as I'm aware they are fully spec'd. I'd add more details but I've already boiled it down to this small example. (Edit: now even smaller, removed out parameter, but not the definition for the argument.)
The end goal I had was for 'inlined method' to be a helper method for the tests, having an input of the result, and the expected ITextObjC[] which represents an array of errors.
Given the minimal, complete, Verifiable example:
public interface test
{
bool testMethod(
bool boolA,
bool boolB);
}
public interface ITestObjC { }
public class TestObjC : ITestObjC { }
[Test]
public void SillyTest2()
{
var fakeTest = Substitute.For<test>();
fakeTest.testMethod( false, false);
ITestObjC[] recOutArr = Arg.Is<ITestObjC[]>(x => x == null);
fakeTest.Received(1).testMethod(
Arg.Is<bool>(false),
Arg.Is<bool>(false));
}
Results in:
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 NSubstitute.Core.Arguments.ArgumentSpecificationFactory.Create(Object argument, IParameterInfo parameterInfo, ISuppliedArgumentSpecifications suppliedArgumentSpecifications)
at NSubstitute.Core.Arguments.MixedArgumentSpecificationsFactory.<>c__DisplayClass3_0.<Create>b__0(Object argument, Int32 i)
at System.Linq.Enumerable.<SelectIterator>d__5`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.CheckReceivedCallsHandler.Handle(ICall call)
at NSubstitute.Routing.Route.<>c__DisplayClass8_0.<Handle>b__0(ICallHandler x)
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.Core.CallRouter.Route(ICall call)
at NSubstitute.Proxies.CastleDynamicProxy.CastleForwardingInterceptor.Intercept(IInvocation invocation)
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Castle.Proxies.testProxy.testMethod(ITestObjA motionEnvelope, ITestObjB motionSeries, Boolean primaryLimits, Boolean testPitch, ITestObjC[]& exceedences)
at HeliSAFE.DataStorage.Tests.SholMonitor.CommonSholMonitorTests.SillyTest2() in D:\Repositories\GitSAFE_Repos\helisafe.container\helisafe\HeliSAFE.DataStorage.Tests\SholMonitor\CommonSholMonitorTests.cs:line 375
on this line:
fakeTest.Received(1).testMethod(
Upvotes: 1
Views: 1837
Reputation: 10484
The short answer is don't use argument matchers outside of a Received
or Returns
.
The longer answer is that to get NSubstitute's syntax it does some questionable things. In this case, every time you do Arg.Is
or Arg.Any
it pushes the argument matcher into a static (threadlocal) queue. When it receives an actual call it then retrieves these argument matchers to work out what calls match (for Received
) or what calls to stub (for Returns
).
In this case three argument matchers are queued, but the fakeTest .Received().testMethod(bool a, bool b)
takes just two, so NSubstitute is not sure where the three argument matchers are meant to go.
As an aside, the detection of these cases and error messages are set to improve with the next version of NSubstitute (after 3.1).
Upvotes: 4
Reputation: 4470
NSubstitute appears to have some sort of completeness check that runs when evaluating Received calls that contain Arg.Is.
Leaving out the Arg.Is in a Received call, or not calling .Received, or commenting out the Orphan argument appears to fix it, but I don't know why.
Upvotes: 0