devlooped/moq · error · ArgumentException

A matching constructor for the given arguments was not…

Error message

A matching constructor for the given arguments was not found on the mocked type.

What it means

In CastleProxyFactory.CreateProxy, Castle DynamicProxy signals that no constructor matching the supplied arguments exists on the mocked type by throwing MissingMethodException; Moq converts this into an ArgumentException with the ConstructorNotFound message. Moq passes constructor arguments only when you call Mock<T> with a ctorArgs array, and those arguments must bind to a real constructor of the (non-interface) mocked type.

Solutions

  1. Check the mocked type's constructors and pass arguments that exactly match one (types and count).
  2. If the class has a parameterless constructor, call new Mock<T>() with no args.
  3. Pass typed values (or null with explicit cast) instead of loosely typed objects so the right overload binds.
  4. If mocking an interface, remove the constructor arguments entirely.

Example fix

// before
var mock = new Mock<MyService>("conn", 42); // ctor takes (string, string)
// after
var mock = new Mock<MyService>("conn", "default");
Defensive patterns

Strategy: validation

Validate before calling

bool ctorMatches = typeof(T).GetConstructors().Any(c =>
    c.GetParameters().Length == args.Length &&
    c.GetParameters().Zip(args, (p, a) => a == null || p.ParameterType.IsInstanceOfType(a)).All(ok => ok));
if (!ctorMatches) throw new InvalidOperationException("No matching constructor for mock args.");

Try / catch

try { var mock = new Mock<T>(args); }
catch (ArgumentException ex) when (ex.Message.Contains("matching constructor")) { /* fix args or use parameterless ctor */ }

Prevention

When it happens

Trigger: new Mock<MyClass>(ctorArgs) where no constructor of MyClass accepts the given number/types of arguments, or passing constructor arguments when mocking an interface/delegate that has no constructor at all.

Common situations: Refactoring a class constructor (changing parameter types or counts) without updating the mock setup in tests; passing nulls or mismatched types so overload resolution fails; copying a mock setup between a class and its interface.

Related errors


AI-assisted analysis of devlooped/moq@89a5be629c (2026-09-16). Data as JSON: /api/errors/f580b7f273dd6827. Report an issue: GitHub.

Appendix: source

Thrown at src/Moq/Interception/CastleProxyFactory.cs:78

            else if (mockType.IsDelegateType())
            {
                var options = new ProxyGenerationOptions();
                options.AddDelegateTypeMixin(mockType);
                var container = GetClassGenerator(mockType).CreateClassProxy(typeof(object), additionalInterfaces, options, new Interceptor(interceptor));
                return Delegate.CreateDelegate(mockType, container, container.GetType().GetMethod("Invoke")!);
            }

            try
            {
                return GetClassGenerator(mockType).CreateClassProxy(mockType, additionalInterfaces, this.generationOptions, arguments, new Interceptor(interceptor));
            }
            catch (TypeLoadException e)
            {
                throw new ArgumentException(string.Format(Resources.TypeNotMockable, mockType), e);
            }
            catch (MissingMethodException e)
            {
                throw new ArgumentException(Resources.ConstructorNotFound, e);
            }
        }

        public override bool IsMethodVisible(MethodInfo method, out string messageIfNotVisible)
        {
            return ProxyUtil.IsAccessible(method, out messageIfNotVisible);
        }

        public override bool IsTypeVisible(Type type)
        {
            return ProxyUtil.IsAccessible(type);
        }

        sealed class Interceptor : Castle.DynamicProxy.IInterceptor
        {
            static readonly MethodInfo proxyInterceptorGetter = typeof(IProxy).GetProperty(nameof(IProxy.Interceptor))!.GetMethod!;

            Moq.IInterceptor interceptor;

View on GitHub (pinned to 89a5be629c)