我如何模拟一个接口 属性 这是一个接口

How do I Mock an interface property that is an interface

public interface IFoo
{
    IFoo2 Foo2 { get; }
}

public interface IFoo2
{
    string FooMethod();
}

假设我有上面的两个接口。我正在尝试模拟在另一个界面上设置为 属性 的界面。这可能吗?

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

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

抱怨无法将 IFoo2 转换为 Moq.Mock<IFoo2>:

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

引用 Object 属性 以访问模拟实例。

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

mockFoo.SetupGet(x => x.Foo2).Returns(mockFoo2.Object);

它不起作用的原因是您在设置外部模拟时忘记了对内部模拟实例的 .Object(参见 Grant Winney 的回答)。

但请注意,您 不必 明确提及内部模拟(您的 mockFoo2)。您可以只向外部模拟传递一个带有额外句点 . ("auto-mocking hierarchies (also known as recursive mocks)") 的 "long" 表达式树。像这样:

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

// use 'mockFoo.Object' for your test