devlooped/moq · error · NotSupportedException
Type to mock ( ) must be an interface, a delegate, or a…
Error message
Type to mock ({0}) must be an interface, a delegate, or a non-sealed, non-static class. What it means
Moq can only generate runtime proxies for interfaces, delegates, or non-sealed, non-static classes. This NotSupportedException is thrown when Type/Mock<T> is given a type that violates these constraints (sealed class, static class, or otherwise unmockable type).
Solutions
- Mock the interface the sealed class implements (e.g. Mock<IFileService> instead of Mock<FileService>).
- Extract an interface or make the class methods virtual and unseal the class if you own it.
- Use a wrapper/adapter (e.g. SystemWrapper-style) around the unmockable type and mock the wrapper.
- For delegates, ensure the type actually is a delegate type; sealed static behavior can be faked by abstracting it away.
Example fix
// before
var mock = new Mock<FileService>(); // FileService is sealed
// after
IFileService svc = mock.Setup(m => m.Read()).Returns("data").Object; Defensive patterns
Strategy: validation
Validate before calling
static void EnsureMockable(Type t)
{
var ti = t.GetTypeInfo();
if (t.IsSealed && !ti.IsDelegate()) throw new InvalidOperationException($"{t.Name} is sealed/static; mock an interface instead");
}
Type guard
static bool IsMockable(Type t) =>
t.IsInterface || t.IsSubclassOf(typeof(Delegate)) ||
(!t.IsSealed && !t.IsStatic());
Try / catch
try { var mock = new Mock<T>(); }
catch (NotSupportedException ex) when (ex.Message.Contains("must be an interface"))
{
// switch to mocking the interface implemented by T
}
Prevention
- Design dependencies as interfaces for testability
- Avoid sealing classes you expect to mock
- Check Type.IsSealed/IsAbstract before creating mocks dynamically
- Use auto-mocking containers configured with interface abstractions
When it happens
Trigger: new Mock<SomeSealedClass>(); mock.Create() on a static class; Mock.Of<T>() with a sealed struct or sealed type; passing a sealed dependency class instead of its interface into MockRepository/fixture auto-mocking.
Common situations: Mocking a sealed third-party class; trying to mock DateTime/string/other special types; attempting to mock a static class for its members; after a type was made sealed during refactoring.
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
- Type to mock ( ) must be an interface, a delegate, or a…
- A matching constructor for the given arguments was not…
- Can't set return value for void method
- Use ItExpr.IsNull rather than a null argument value, as it…
- Member is not supported for protected mocking.
AI-assisted analysis of devlooped/moq@89a5be629c (2026-09-16).
Data as JSON: /api/errors/bbca9adc803769d6.
Report an issue: GitHub.
Appendix: source
Thrown at src/Moq/Guard.cs:212
{
throw new ArgumentException(Resources.ArgumentCannotBeEmpty, paramName);
}
}
public static void NotField(MemberExpression memberAccess)
{
if (memberAccess.Member is FieldInfo)
throw new NotSupportedException(
string.Format(
Resources.FieldsNotSupported,
memberAccess.ToStringFixed()));
}
public static void IsMockable(Type type)
{
if (!type.IsMockable())
{
throw new NotSupportedException(
string.Format(
Resources.TypeNotMockable,
type.GetFormattedName()));
}
}
public static void Positive(TimeSpan delay)
{
if (delay <= TimeSpan.Zero)
{
throw new ArgumentException(Resources.DelaysMustBeGreaterThanZero);
}
}
public static void CanRead(PropertyInfo property)
{
if (!property.CanRead(out _))
{View on GitHub (pinned to 89a5be629c)