devlooped/moq · error · NotSupportedException

Resources.CallBaseCannotBeUsedWithDelegateMocks

Error message

Resources.CallBaseCannotBeUsedWithDelegateMocks

What it means

Moq throws this NotSupportedException when CallBase is set to true on a mock whose mocked type is a delegate. CallBase means 'invoke the base class implementation', which is meaningless for delegates since there is no overridable base implementation to call.

Solutions

  1. Remove CallBase = true from the delegate mock and define behavior with Setup instead.
  2. If base behavior is genuinely needed, mock the concrete class rather than a delegate.
  3. Only set CallBase conditionally: if (!typeof(T).IsDelegateType()) mock.CallBase = true;

Example fix

// before
var mock = new Mock<EventHandler> { CallBase = true };
// after
var mock = new Mock<EventHandler>();
Defensive patterns

Strategy: validation

Validate before calling

if (typeof(T).IsSubclassOf(typeof(Delegate)) && enableCallBase)
    throw new NotSupportedException("CallBase is not supported for delegate mocks.");

Type guard

bool CanUseCallBase<T>() => !typeof(T).IsSubclassOf(typeof(Delegate));

Try / catch

try { mock.CallBase = true; } catch (NotSupportedException) { /* delegate mock: skip CallBase */ }

Prevention

When it happens

Trigger: new Mock<SomeDelegateType> { CallBase = true } — assigning true to Mock<T>.CallBase (src/Moq/Mock`1.cs:246) when MockedType.IsDelegateType().

Common situations: Object-initializer code reused across mock factories that always sets CallBase = true; mocking delegates for HttpClient handlers or callbacks and blindly enabling CallBase.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at src/Moq/Mock`1.cs:246

            }
        }

        #endregion

        #region Properties

        /// <inheritdoc/>
        public override MockBehavior Behavior => this.behavior;

        /// <inheritdoc/>
        public override bool CallBase
        {
            get => this.callBase;
            set
            {
                if (value && this.MockedType.IsDelegateType())
                {
                    throw new NotSupportedException(Resources.CallBaseCannotBeUsedWithDelegateMocks);
                }

                this.callBase = value;
            }
        }

        internal override object?[] ConstructorArguments => this.constructorArguments;

        internal override Dictionary<Type, object?> ConfiguredDefaultValues => this.configuredDefaultValues;

        /// <summary>
        /// Gets or sets the <see cref="DefaultValueProvider"/> instance that will be used
        /// e. g. to produce default return values for unexpected invocations.
        /// </summary>
        public override DefaultValueProvider DefaultValueProvider
        {
            get => this.defaultValueProvider;
            set => this.defaultValueProvider = value ?? throw new ArgumentNullException(nameof(value));

View on GitHub (pinned to 89a5be629c)