-
Notifications
You must be signed in to change notification settings - Fork 277
Open
Description
Describe the bug
As soon as the readonly struct Path in the repro below has a call to another ctor the following AmbiguousArgumentsException is thrown:
NSubstitute.Exceptions.AmbiguousArgumentsException
HResult=0x80131500
Message=Cannot determine argument specifications to use. Please use specifications for all arguments of the same type.
Method signature:
Do<Parent, Base, Child>(Path<Base, Parent>, Func<Parent, Base>)
Method arguments (possible arg matchers are indicated with '*'):
Do<Parent, Base, Child>(NSubRepro.Path`2[NSubRepro.Base,NSubRepro.Parent], *<null>*)
All queued specifications:
any Path<Base, Parent>
any Func<Parent, Child>
Matched argument specifications:
Do<Parent, Base, Child>(NSubRepro.Path`2[NSubRepro.Base,NSubRepro.Parent], ???)
Source=NSubstitute
StackTrace:
at NSubstitute.Core.Arguments.ArgumentSpecificationsFactory.Create(IList`1 argumentSpecs, Object[] arguments, IParameterInfo[] parameterInfos, MethodInfo methodInfo, MatchArgs matchArgs)
at NSubstitute.Core.CallSpecificationFactory.CreateFrom(ICall call, MatchArgs matchArgs)
at NSubstitute.Routing.Handlers.RecordCallSpecificationHandler.Handle(ICall call)
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 NSubstitute.Proxies.CastleDynamicProxy.ProxyIdInterceptor.Intercept(IInvocation invocation)
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Castle.Proxies.ObjectProxy.Do[TParent,TBaseChild,TChild](Path`2 parentPath, Func`2 relation)
at NSubRepro.Program.Main(String[] args) in D:\Repros\NSubRepro\NSubRepro\Program.cs:line 15
To Reproduce
Repro code:
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Threading.Tasks;
using NSubstitute;
namespace NSubRepro
{
internal class Program
{
static void Main(string[] args)
{
var testMock = Substitute.For<ITest>();
testMock.Do<Parent, Base, Child>(Arg.Any<Path<Base, Parent>>(), Arg.Any<Func<Parent, Child>>()).Returns(Task.CompletedTask);
}
}
public readonly struct Path<TVisit, TMatch>
{
private readonly ImmutableList<TVisit> _nodes;
// As soon as the call to the other ctor is commented out, it works
public Path() : this(ImmutableList<TVisit>.Empty)
{
}
private Path(TVisit node) : this(ImmutableList<TVisit>.Empty.Add(node))
{
}
private Path(ImmutableList<TVisit> nodes)
{
_nodes = nodes;
}
}
public interface ITest
{
Task Do<TParent, TBaseChild, TChild>(Path<Base,TParent> parentPath, Func<TParent, TBaseChild> relation)
where TParent : Base where TBaseChild : Base where TChild : TBaseChild;
}
public abstract class Base;
public sealed class Parent : Base
{
public List<Child> Children { get; } = [];
}
public sealed class Child : Base;
}As soon as the this call in the Path ctor is commented, the exception is gone. I'm not sure how that call is responsible for that exception.
Expected behaviour
No exception
Environment:
- NSubstitute version: 5.3.0
- NSubstitute.Analyzers version: Csharp 1.0.17
- Platform: .NET 9, x64 Windows 11
Metadata
Metadata
Assignees
Labels
No labels