Carlo V. Dango
Carlo V. Dango

Reputation: 13852

Mocking interface re-defining a property using MOQ 4.0

In older versions of MOQ the following code would work fine (eg. 3.1.416.3). It doesn't anymore. How do I change my mock into working? The problem is that the interface inherits another interface and redefines a field. Hence my mock now needs be configured with values for both fields as this is used in my Code1() and Code2() calls

public interface I
{
    string field { get; }
}

public interface IModi : I
{
    new string field { get; set; }
}

public class P : IModi
{
    private string val;

    string I.field
    {
        get { return val; }
    }

    public string field
    {
        get { return val; }
        set { val = value; }
    }

    public static void Code1(I p)
    {
        Console.WriteLine(p.field);
    }

    public static void Code2(IModi p)
    {
        Code1(p);
        Console.WriteLine(p.field);
    }
}

The failing test

[TestFixture]
class MoqTests
{
    [Test]
    public void testinterfaces()
    {
        MockRepository factory = new MockRepository(MockBehavior.Strict);
        var mock = factory.Create<IModi>();
        mock.Setup(x => x.field).Returns("hello");
        P.code2(mock.Object);
    }
}

Error

Moq.MockException : I.field invocation failed with mock behavior Strict. All invocations on the mock must have a corresponding setup.

Upvotes: 1

Views: 2246

Answers (1)

Igor Zevaka
Igor Zevaka

Reputation: 76520

This is possible using Mock<T>.As<T>() method. As() adds an interface to the mock, thus allowing you to specify different setups for different interfaces.

Word of warning for hidden methods/properties (which are pretty evil if you ask me, I normally avoid using those). You must set up the hidden method first, before setting up the outermost method, otherwise the innermost setup will fire for both invocations. This looks like a Moq bug to me.

This should work:

[Test]
public void testinterfaces()
{
    MockRepository factory = new MockRepository(MockBehavior.Strict);
    var mock = factory.Create<IModi>();
    mock.As<I>.Setup(x => x.field).Returns("hello");
    mock.Setup(x => x.field).Returns("hello");
    P.code2(mock.Object);
}

Upvotes: 5

Related Questions