devlooped/moq · error · ArgumentException
Property . does not have a getter.
Error message
Property {0}.{1} does not have a getter. What it means
Moq throws this ArgumentException when setting up or verifying a property that has no getter (write-only property). Property setups like mock.Setup(m => m.Prop) require a readable property to intercept the get call.
Solutions
- Add a getter to the property on the mocked type if you control it.
- Use SetupSet/VerifySet for setter-only properties instead of Setup/VerifyGet.
- Track the value via a backing field captured in a callback on SetupSet, then assert on that field.
- Mock an interface that exposes the property as read-write if available.
Example fix
// before
mock.Setup(m => m.Output).Returns("x"); // Output is write-only
// after
mock.SetupSet(m => m.Output = It.IsAny<string>()).Callback(v => captured = v); Defensive patterns
Strategy: type-guard
Validate before calling
static bool HasGetter(Type t, string name) =>
t.GetProperty(name)?.GetGetMethod(nonPublic: false) != null;
Type guard
static bool IsReadable(System.Reflection.PropertyInfo p) => p.CanRead;
Try / catch
try { mock.Setup(expr).Returns(v); }
catch (ArgumentException ex) when (ex.Message.Contains("does not have a getter"))
{
// use SetupSet/VerifySet or add a getter to the property
}
Prevention
- Check PropertyInfo.CanRead before Setup/VerifyGet
- Prefer read-write properties in mocked contracts
- Use SetupSet for write-only properties
- Review property refactorings that remove getters
When it happens
Trigger: mock.Setup(m => m.WriteOnlyProp) or mock.VerifyGet(m => m.WriteOnlyProp) on a property that only defines a setter; also setup-property paths (SetupProperty) on getter-less properties.
Common situations: Mocking types with write-only properties (common in serialization/config sink types); after refactoring removed the getter; incorrect property chosen that is setter-only.
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
- Property . does not have a setter.
- Unsupported expression
- Resources.ArgumentMatcherWillNeverMatch (formatted with…
- Resources.UnsupportedExpression (formatted with…
- Resources.SetupNotEventAdd (formatted with part.Expression)
AI-assisted analysis of devlooped/moq@89a5be629c (2026-09-16).
Data as JSON: /api/errors/a674097a53396a41.
Report an issue: GitHub.
Appendix: source
Thrown at src/Moq/Guard.cs:231
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 _))
{
throw new ArgumentException(string.Format(
CultureInfo.CurrentCulture,
Resources.PropertyGetNotFound,
property.DeclaringType!.Name, property.Name));
}
}
public static void CanWrite(PropertyInfo property)
{
if (!property.CanWrite(out _))
{
throw new ArgumentException(string.Format(
CultureInfo.CurrentCulture,
Resources.PropertySetNotFound,
property.DeclaringType!.Name, property.Name));
}
}
}
}View on GitHub (pinned to 89a5be629c)