devlooped/moq · error · InvalidOperationException

Resources.AlreadyInitialized

Error message

Resources.AlreadyInitialized

What it means

Moq throws this InvalidOperationException when As<TInterface>() is called on a mock whose underlying object is already initialized, and the mock does not already implement the requested interface. After the mock object has been created (e.g. after Object was accessed or setups executed), late-adding a brand-new interface would change the type of an already-instantiated object, which is unsafe.

Solutions

  1. Call As<TInterface>() before first accessing mock.Object or invoking setups.
  2. Check mock.IsObjectInitialized / whether the interface is already implemented before calling As.
  3. Create a new mock including all needed interfaces up front (or via additionalInterfaces at construction).

Example fix

// before
var obj = mock.Object;
mock.As<IExtra>();
// after
mock.As<IExtra>();
var obj = mock.Object;
Defensive patterns

Strategy: validation

Validate before calling

if (mock.IsObjectInitialized && !alreadyImplements)
    throw new InvalidOperationException("Call As<T> before first accessing mock.Object.");

Try / catch

try { mock.As<IExtra>(); } catch (InvalidOperationException) { mock = new Mock<T>(); mock.As<IExtra>(); }

Prevention

When it happens

Trigger: Calling mock.As<INewInterface>() after mock.Object has been materialized, where ImplementsInterface(INewInterface) is false (src/Moq/Mock`1.cs:394).

Common situations: Accessing mock.Object early (passing it to SUT setup) and later extending the mock with As<T> in verification code; factory helpers that finalize mocks then callers that extend them.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at src/Moq/Mock`1.cs:394

        ///   </code>
        /// </example>
        public override Mock<TInterface> As<TInterface>()
        {
            var interfaceType = typeof(TInterface);

            if (!interfaceType.IsInterface)
            {
                throw new ArgumentException(Resources.AsMustBeInterface);
            }

            if (typeof(TInterface) == typeof(T))
            {
                return (Mock<TInterface>)(Mock)this;
            }

            if (this.IsObjectInitialized && this.ImplementsInterface(interfaceType) == false)
            {
                throw new InvalidOperationException(Resources.AlreadyInitialized);
            }

            if (this.AdditionalInterfaces.Contains(interfaceType) == false)
            {
                // We get here for either of two reasons:
                //
                // 1. We are being asked to implement an interface that the mocked type does *not* itself
                //    inherit or implement. We need to hand this interface type to DynamicProxy's
                //    `CreateClassProxy` method as an additional interface to be implemented.
                //
                // 2. The user is possibly going to create a setup through an interface type that the
                //    mocked type *does* implement. Since the mocked type might implement that interface's
                //    methods non-virtually, we can only intercept those if DynamicProxy reimplements the
                //    interface in the generated proxy type. Therefore we do the same as for (1).
                this.AdditionalInterfaces.Add(interfaceType);
            }

            return new AsInterface<TInterface>(this);

View on GitHub (pinned to 89a5be629c)