devlooped/moq · error · ArgumentException
Cannot set up . because it is not accessible to the proxy…
Error message
Cannot set up {0}.{1} because it is not accessible to the proxy generator used by Moq:
{2} What it means
Guard.IsVisibleToProxyFactory checks that the method being set up is visible to the dynamic proxy generator Moq uses (e.g. internal members not exposed via InternalsVisibleTo). If ProxyFactory reports the method as not visible, Moq throws ArgumentException with the type, method, and the proxy generator's explanation.
Solutions
- Add [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] to the assembly containing the type (include PublicKey if strong-named).
- Make the member public.
- Mock a public interface instead of the internal type/member.
- Move tests into the same assembly or adjust visibility of the member.
Example fix
// before
// AssemblyWithInternal: internal interface IThing { }
mock.Setup(t => t.DoWork()); // throws
// after
// Add to AssemblyWithInternal Properties/AssemblyInfo.cs:
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
mock.Setup(t => t.DoWork()); Defensive patterns
Strategy: validation
Validate before calling
var m = typeof(Thing).GetMethod("DoWork", BindingFlags.NonPublic | BindingFlags.Instance)!;
bool visible = m.IsPublic || m.IsFamilyOrAssembly || (m.IsAssembly && InternalsVisible.ToProxy()); Try / catch
try { mock.Setup(t => t.DoWork()); }
catch (ArgumentException ex) when (ex.Message.Contains("not accessible to the proxy generator")) { /* add InternalsVisibleTo("DynamicProxyGenAssembly2") */ throw; } Prevention
- Add [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] (with public key for strong-named assemblies) when mocking internals.
- Prefer mocking public interfaces.
- Keep visibility modifiers intentional and documented per assembly.
When it happens
Trigger: Setting up or verifying internal or protected-internal members of an assembly that has not granted visibility to Moq's proxy (missing [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]) or to the test assembly.
Common situations: Mocking internal interfaces/classes across assembly boundaries; tests in a separate assembly mocking internal members; strong-named assemblies where InternalsVisibleTo needs the public key; switching from same-assembly to separate test-assembly layouts.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- Unsupported expression
- Could not determine the correct positions for all argument…
- The return type of the last member shown above is not…
- Value cannot be null. (Parameter 'value')
- Unsupported expression
AI-assisted analysis of devlooped/moq@89a5be629c (2026-09-16).
Data as JSON: /api/errors/d733cbb3e1b425c4.
Report an issue: GitHub.
Appendix: source
Thrown at src/Moq/Guard.cs:116
else if (!method.CanOverride())
{
throw new NotSupportedException(
string.Format(
CultureInfo.CurrentCulture,
Resources.UnsupportedExpressionWithHint,
expression.ToStringFixed(),
string.Format(
CultureInfo.CurrentCulture,
Resources.UnsupportedNonOverridableMember,
$"{method.DeclaringType!.GetFormattedName()}.{method.Name}")));
}
}
public static void IsVisibleToProxyFactory(MethodInfo method)
{
if (ProxyFactory.Instance.IsMethodVisible(method, out string? messageIfNotVisible) == false)
{
throw new ArgumentException(string.Format(
CultureInfo.CurrentCulture,
Resources.MethodNotVisibleToProxyFactory,
method.DeclaringType!.Name,
method.Name,
messageIfNotVisible));
}
}
public static void IsEventAdd(LambdaExpression expression, string paramName)
{
Debug.Assert(expression != null);
switch (expression.Body.NodeType)
{
case ExpressionType.Call:
var call = (MethodCallExpression)expression.Body;
if (call.Method.IsEventAddAccessor()) return;
break;View on GitHub (pinned to 89a5be629c)