{"record":{"id":"d6e335f35c8c9151","repo":"devlooped/moq","slug":"type-to-mock-0-must-be-an-interface-a-delegate-or-a-non-d6e335","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":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Moq/Interception/CastleProxyFactory.cs","lineNumber":74,"sourceCode":"                // While `CreateClassProxy` could also be used for interface types,\n                // `CreateInterfaceProxyWithoutTarget` is much faster (about twice as fast):\n                return generator.CreateInterfaceProxyWithoutTarget(mockType, additionalInterfaces, this.generationOptions, new Interceptor(interceptor));\n            }\n            else if (mockType.IsDelegateType())\n            {\n                var options = new ProxyGenerationOptions();\n                options.AddDelegateTypeMixin(mockType);\n                var container = GetClassGenerator(mockType).CreateClassProxy(typeof(object), additionalInterfaces, options, new Interceptor(interceptor));\n                return Delegate.CreateDelegate(mockType, container, container.GetType().GetMethod(\"Invoke\")!);\n            }\n\n            try\n            {\n                return GetClassGenerator(mockType).CreateClassProxy(mockType, additionalInterfaces, this.generationOptions, arguments, new Interceptor(interceptor));\n            }\n            catch (TypeLoadException e)\n            {\n                throw new ArgumentException(string.Format(Resources.TypeNotMockable, mockType), e);\n            }\n            catch (MissingMethodException e)\n            {\n                throw new ArgumentException(Resources.ConstructorNotFound, e);\n            }\n        }\n\n        public override bool IsMethodVisible(MethodInfo method, out string messageIfNotVisible)\n        {\n            return ProxyUtil.IsAccessible(method, out messageIfNotVisible);\n        }\n\n        public override bool IsTypeVisible(Type type)\n        {\n            return ProxyUtil.IsAccessible(type);\n        }\n\n        sealed class Interceptor : Castle.DynamicProxy.IInterceptor","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/devlooped/moq/blob/89a5be629c752960fe403e95ff583e4ae6f00542/src/Moq/Interception/CastleProxyFactory.cs#L56-L92","documentation":"Moq creates mock objects by generating a dynamic proxy via Castle DynamicProxy in CastleProxyFactory.CreateProxy. When the proxy generator fails with a TypeLoadException, Moq rethrows it as an ArgumentException using the TypeNotMockable resource: the target type must be an interface, a delegate, or a non-sealed, non-static class. Sealed classes, static classes, and types with inaccessible internals cannot be proxied.","triggerScenarios":"Calling Mock.Of<T>() or new Mock<T>() where T is a sealed class (e.g. string or a sealed DTO), a static class, or a non-public/inaccessible class whose methods Castle cannot override; CreateProxy catches TypeLoadException and throws this ArgumentException.","commonSituations":"Attempting to mock types from the BCL like string, HttpClient (partially), or framework sealed types; mocking third-party classes that were made sealed in a newer library version; trying to mock internal classes without InternalsVisibleTo(\"DynamicProxyGenAssembly2\").","solutions":["Mock the interface the class implements instead of the sealed class itself.","Remove 'sealed' from the class (and make mocked members public virtual) if you own the code.","For internal types, add [assembly: InternalsVisibleTo(\"DynamicProxyGenAssembly2\")] to the mocked assembly.","Wrap the unmockable dependency behind your own interface for testability."],"exampleFix":"// before\nvar mock = new Mock<string>(); // string is sealed\n// after\nvar mock = new Mock<IMessageBuilder>(); // mock the interface instead","handlingStrategy":"validation","validationCode":"static bool IsMockable(Type t) =>\n    t.IsInterface || t.IsSubclassOf(typeof(Delegate)) ||\n    (!t.IsSealed && !t.IsStatic() && !t.IsAbstractWithNoCtorAccessible());\n// simplest safe check:\n// if (type.IsSealed || type.IsAbstract) throw new InvalidOperationException($\"{type.Name} cannot be mocked; mock an interface instead.\");","typeGuard":"static bool CanMock(Type t) => t.IsInterface || (!t.IsSealed && !t.IsAbstract || t.IsSubclassOf(typeof(Delegate)));","tryCatchPattern":"try { var mock = new Mock<T>(); }\ncatch (ArgumentException ex) when (ex.InnerException is TypeLoadException) { /* fall back to interface mock or manual fake */ }","preventionTips":["Design dependencies as interfaces so tests never mock concrete classes.","Never mark classes you intend to mock as sealed or static.","Make mocked members public virtual.","Add InternalsVisibleTo(\"DynamicProxyGenAssembly2\") if mocking internal types."],"tags":["moq","mocking","sealed-class","proxy-generation","csharp"],"backgroundTag":"invalid-argument-value","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"}