Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I Mock an interface property that is an interface

public interface IFoo
{
    IFoo2 Foo2 { get; }
}

public interface IFoo2
{
    string FooMethod();
}

Say I have the 2 interfaces above. I am trying to mock the interface that is set up as a property on the other interface. Is this possible?

Mock<IFoo> mockFoo = new Mock<IFoo>();
Mock<IFoo2> mockFoo2 = new Mock<IFoo2>();

mockfoo.SetupGet<IFoo2>(x => x.Foo2).Returns(mockFoo2);

Complains that it cant convert a IFoo2 to Moq.Mock<IFoo2>:

Error CS1503 Argument 1: cannot convert from 'Moq.Mock<IFoo2>' to 'IFoo2'

like image 449
Ryan Avatar asked Nov 01 '25 14:11

Ryan


2 Answers

Reference the Object property to access the mocked instance.

Mock<IFoo> mockFoo = new Mock<IFoo>();
Mock<IFoo2> mockFoo2 = new Mock<IFoo2>();

mockFoo.SetupGet(x => x.Foo2).Returns(mockFoo2.Object);
like image 167
Grant Winney Avatar answered Nov 04 '25 07:11

Grant Winney


The reason why it did not work was that you forgot .Object on the inner mock instance when you set up the outer mock (see Grant Winney's answer).

But note that you do not have to mention the inner mock (your mockFoo2) explicitly. You can just pass the outer mock a "long" expression tree with an extra period . ("auto-mocking hierarchies (also known as recursive mocks)"). Like this:

Mock<IFoo> mockFoo = new Mock<IFoo>();
mockFoo.Setup(x => x.Foo2.FooMethod()).Returns("your string");

// use 'mockFoo.Object' for your test
like image 39
Jeppe Stig Nielsen Avatar answered Nov 04 '25 06:11

Jeppe Stig Nielsen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!