{"record":{"id":"bbca9adc803769d6","repo":"devlooped/moq","slug":"type-to-mock-0-must-be-an-interface-a-delegate-or-a-non","errorCode":null,"errorMessage":"Type to mock ({0}) must be an interface, a delegate, or a non-sealed, non-static class.","messagePattern":"Type to mock \\((.+?)\\) must be an interface, a delegate, or a non-sealed, non-static class\\.","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"src/Moq/Guard.cs","lineNumber":212,"sourceCode":"            {\n                throw new ArgumentException(Resources.ArgumentCannotBeEmpty, paramName);\n            }\n        }\n\n        public static void NotField(MemberExpression memberAccess)\n        {\n            if (memberAccess.Member is FieldInfo)\n                throw new NotSupportedException(\n                    string.Format(\n                        Resources.FieldsNotSupported,\n                        memberAccess.ToStringFixed()));\n        }\n\n        public static void IsMockable(Type type)\n        {\n            if (!type.IsMockable())\n            {\n                throw new NotSupportedException(\n                    string.Format(\n                        Resources.TypeNotMockable,\n                        type.GetFormattedName()));\n            }\n        }\n\n        public static void Positive(TimeSpan delay)\n        {\n            if (delay <= TimeSpan.Zero)\n            {\n                throw new ArgumentException(Resources.DelaysMustBeGreaterThanZero);\n            }\n        }\n\n        public static void CanRead(PropertyInfo property)\n        {\n            if (!property.CanRead(out _))\n            {","sourceCodeStart":194,"sourceCodeEnd":230,"githubUrl":"https://github.com/devlooped/moq/blob/89a5be629c752960fe403e95ff583e4ae6f00542/src/Moq/Guard.cs#L194-L230","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nvar mock = new Mock<FileService>(); // FileService is sealed\n// after\nIFileService svc = mock.Setup(m => m.Read()).Returns(\"data\").Object;","handlingStrategy":"validation","validationCode":"static void EnsureMockable(Type t)\n{\n    var ti = t.GetTypeInfo();\n    if (t.IsSealed && !ti.IsDelegate()) throw new InvalidOperationException($\"{t.Name} is sealed/static; mock an interface instead\");\n}\n","typeGuard":"static bool IsMockable(Type t) =>\n    t.IsInterface || t.IsSubclassOf(typeof(Delegate)) ||\n    (!t.IsSealed && !t.IsStatic());\n","tryCatchPattern":"try { var mock = new Mock<T>(); }\ncatch (NotSupportedException ex) when (ex.Message.Contains(\"must be an interface\"))\n{\n    // switch to mocking the interface implemented by T\n}\n","preventionTips":["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"],"tags":["moq","mocking","sealed-class","proxy-generation"],"backgroundTag":"unsupported-operation","analyzedSha":"89a5be629c752960fe403e95ff583e4ae6f00542","analyzedAt":"2026-09-16T05:31:39.496Z","contentChangedAt":"2026-09-16T05:31:39.496Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}