【问题标题】:How to mock an object that extends a class and implements an interface?如何模拟一个扩展类并实现接口的对象?
【发布时间】:2011-12-20 09:55:43
【问题描述】:

我有这门课:

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
        }
    }
}

我的情况是:

    void main()
    {
        MyClass obj = new MyClass(new FooClass());
        obj.DoSomething();
    } 

我想为 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);

【问题讨论】:

  • 很高兴这不起作用 - 这是您的类设计中的代码异味:您不应该将类型为 IFoo 的依赖项转换为 BaseFoo。您违反了 Liskov 替换原则,并且以我能想到的任何方式执行此操作都是错误的选择。
  • 我很想在这个问题上选择-1...

标签: c# unit-testing mocking nunit


【解决方案1】:

您的设计真正要表达的是您的类MyClass 不依赖于IFoo,它依赖于派生自BaseFoo 的类实例 实现@987654324 @。在这种情况下,最好引入一个统一接口,然后您可以将其用作依赖项和模拟:

interface IFooBar
{
  bool BoolProp { get; set; }
  void Method();
}  

【讨论】:

    【解决方案2】:

    如何声明一个派生自 BaseFoo 并实现 IFoo 的抽象类(BaseFooFoo?)。然后你可以将 BaseFooFoo 显示给 moq。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-13
      • 2016-04-28
      • 1970-01-01
      相关资源
      最近更新 更多