如何模拟扩展类并实现接口的对象?

Mau*_*chi 4 c# nunit unit-testing mocking

我有这门课:

public class BaseFoo
{
    public bool BoolProp { get; set; }
}

public interface IFoo {
    void Method();
}

public class FooClass : BaseFoo, IFoo
{
    public void Method()
    {
        // DoSomething
    }
}

public class MyClass
{
    IFoo foo; // 
    public MyClass(IFoo foo)
    {
        this.foo = foo;
    }

    public void DoSomething()
    {
        if (((FooClass)foo).BoolProp)
        {
            // yeah
        }
        else
        {
            //bad
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我的情况是:

    void main()
    {
        MyClass obj = new MyClass(new FooClass());
        obj.DoSomething();
    } 
Run Code Online (Sandbox Code Playgroud)

我想为IFoo接口创建一个模拟对象,它允许我模拟BaseFoo类,因为我需要总是避免运行"if(((FooClass)foo).BoolProp)"的"else"分支. MyClass.DoSomething()方法.
那么,我怎样才能创建一个模拟对象,允许我模拟MyClass中使用的BaseFoo.BoolProp的行为(这将采用IFoo的模拟对象)?
我没有任何结果,因为"BoolProp"不是虚拟的,我无法更改它,因为它是.NET Framework类的一部分:

  var cMock = new Mock<BaseFoo>();
  var iMock = cMock.As<IFoo>();

  cMock.Setup(c => c.BaseProp).Returns(true);
  MyClass myClass = new MyClass(iMock.Object);
Run Code Online (Sandbox Code Playgroud)

Bro*_*ass 5

你的设计真正说的是你的类MyClass没有依赖IFoo,它依赖于派生BaseFoo 实现的类实例IFoo.在这种情况下,最好引入一个统一的接口,然后可以将其用作依赖项和mock:

interface IFooBar
{
  bool BoolProp { get; set; }
  void Method();
}  
Run Code Online (Sandbox Code Playgroud)