接口模拟上的 Moq CallBase

sou*_*mer 5 c# moq

假设我们有以下设置:

public interface IBase
{
    void Foo();
}

public class Base : IBase
{
    public virtual void Foo()
    {
        Console.WriteLine("Called Base.Foo()");
    }
}

public interface IChild : IBase
{
    void Bar();
}

public class Child : Base, IChild
{
    public virtual void Bar()
    {
        Console.WriteLine("Called Child.Bar()");
    }
}
Run Code Online (Sandbox Code Playgroud)

当模拟Child对象时,一切正常:

var child = new Mock<Child> { CallBase = true };

child.Object.Bar();
child.Object.Foo();
Run Code Online (Sandbox Code Playgroud)

输出是:

调用 Child.Bar()
调用 Base.Foo()

但是当IChild模拟接口时,控制台上不会打印任何内容:

var child = new Mock<IChild> { CallBase = true };

child.Object.Bar();
child.Object.Foo();
Run Code Online (Sandbox Code Playgroud)

假设我无法模拟该Child对象,因为没有无参数构造函数(依赖注入)。

我知道我可以执行以下操作:

child.Setup(c => c.Bar()).Callback(() =>
{
    // Copy paste bar-method body
});

child.Setup(c => c.Foo()).Callback(() =>
{
    // Copy paste foo-method body
});
Run Code Online (Sandbox Code Playgroud)

但那会非常难看。
有没有使用干净的解决方案Mock<IChild>

Bru*_*ndo 2

只要您模拟接口,您就无法访问或了解有关真实类的信息,这解释了为什么您没有得到任何输出(但我想您明白这一点)。

不幸的是,如果您选择模拟一个接口(根据定义,该接口没有任何行为),那么使事情发生的唯一方法就是按照您的方式设置方法。

另一种“肮脏”的方法是,如果方法的内容仅使用公共属性和方法,则对您的子类和基类使用方法扩展。

public static class ChildExtension
{
    public static void Bar(this Child child)
    {
        Console.WriteLine("Called Child.Bar()");
    }
}
Run Code Online (Sandbox Code Playgroud)