devlooped/moq · error · NotSupportedException

ExpectSet has been renamed to SetupSet, and the new syntax…

Error message

ExpectSet has been renamed to SetupSet, and the new syntax allows you to pass the value in the expression itself, like f => f.Value = 25. (thrown unconditionally via [Obsolete(..., true)])

What it means

Moq's legacy ExpectSet<TProperty>(expression, value) is marked [Obsolete(..., true)] — a compile-time error API — and its body throws NotSupportedException if somehow invoked. It was replaced by the SetupSet syntax where the assigned value is written directly into the lambda expression.

Solutions

  1. Replace ExpectSet(expr, value) with SetupSet: mock.SetupSet(m => m.Value = 25).
  2. Use It.Is<TProperty> for flexible matching: mock.SetupSet(m => m.Value = It.Is<int>(v => v > 0)).
  3. Run the compiler first — with true-as-error Obsolete, the build points at every call site to migrate.

Example fix

// before
mock.ExpectSet(f => f.Value, 25);
// after
mock.SetupSet(f => f.Value = 25);
Defensive patterns

Strategy: try-catch

Validate before calling

if (methodBeingCalledIs("ExpectSet")) throw new InvalidOperationException("Use SetupSet instead.");

Try / catch

try { legacyMock.ExpectSet(f => f.Value, 25); } catch (NotSupportedException) { mock.SetupSet(f => f.Value = 25); }

Prevention

When it happens

Trigger: Calling mock.ExpectSet(m => m.Value, 25) — any invocation of the obsolete ExpectSet overload in src/Moq/Obsolete/Mock.Generic.Legacy.cs:68; compilation itself fails when the API is referenced.

Common situations: Upgrading old Moq 2.x/3.x test code (pre-4.0 'Expect' era) to modern Moq; copy-pasting legacy example snippets from old blog posts.

Understand the failure class

Background: "is deprecated and will be removed" — deprecation warnings for old API names, keywords, and options, and how to migrate before the removal release — this error's family across 29 libraries.

Related errors


AI-assisted analysis of devlooped/moq@89a5be629c (2026-09-16). Data as JSON: /api/errors/42647bb6f82152ed. Report an issue: GitHub.

Appendix: source

Thrown at src/Moq/Obsolete/Mock.Generic.Legacy.cs:68

        /// <summary>
        /// Obsolete.
        /// </summary>
        [Obsolete("ExpectSet has been renamed to SetupSet.", false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public ISetupSetter<T, TProperty> ExpectSet<TProperty>(Expression<Func<T, TProperty>> expression)
        {
            return this.SetupSet(expression);
        }

        /// <summary>
        /// Obsolete.
        /// </summary>
        [Obsolete("ExpectSet has been renamed to SetupSet, and the new syntax allows you to pass the value in the expression itself, like f => f.Value = 25.", true)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public ISetupSetter<T, TProperty> ExpectSet<TProperty>(Expression<Func<T, TProperty>> expression, TProperty value)
        {
            throw new NotSupportedException();
        }
    }

    /// <summary>
    /// Contains obsolete API members as extension methods so that existing code continues to compile,
    /// but new code doesn't see them.
    /// </summary>
    [EditorBrowsable(EditorBrowsableState.Never)]
    public static class MockLegacyExtensions
    {
        /// <summary>
        /// Obsolete.
        /// </summary>
        [EditorBrowsable(EditorBrowsableState.Never)]
        [Obsolete("The new syntax allows you to pass the value in the expression itself, like f => f.Value = 25.", true)]
        public static ISetupSetter<T, TProperty> SetupSet<T, TProperty>(this Mock<T> mock, Expression<Func<T, TProperty>> expression, TProperty value)
            where T : class
        {

View on GitHub (pinned to 89a5be629c)