如何使用MOQ框架为抽象基类创建Mock?

时间:2011-05-23 18:01:15

标签: unit-testing moq

我想为MyClass编写单元测试,但它的基类是一个抽象类。

public class MyClass : AbstractBaseClass
{
}

我想模拟AbstractBase类,以便在创建我想要测试的MyClass实例时可以跳过其构造函数中的一些逻辑。无论如何我能做到吗?

//Unit Test
var test = new Mock<IInterface>();
var derivedclass = new DerivedClass(test.Object);

test.Setup(d=>d.MyMethod(It.IsAny<string>()).returns(2);
derivedclass.MyMethod("hello");


// Derived Class
class DerivedClass : AbstractClass{

     //constuctor
    public DerivedClass(IInterface interface){
        _interface = interface;
    }
    public MyMethod(string str){
        return 2;
    }
}

//Abstract Class
public abstract class AbstractClass
{

 // This method gets called when i create the  instance of the derived class in my unit   
  test..

   protected AbstractedClass() : this(new SomeOtherClass()){
       DoSomethingElse();    /// I want to skip this method or mock it.
   }
 }

2 个答案:

答案 0 :(得分:6)

通过继承基类来扩展它。它更多的是让您的代码进入可测试状态,而不是让Moq为您工作。

  1. 您可以使用合成而不是基类,然后使用可以模拟的依赖注入(通过接口)。
  2. 或者,如果你必须继承,那么将你不想运行的逻辑提取到另一个通过依赖注入再次注入的类中。
  3. 或者让您不想运行的逻辑成为您可以模拟的虚拟方法的一部分。 (比如@Ohad Horesh的回答:)

    public virtual void DoSomethingElse();
    
    mock.Setup(abs => abs.Foo());  //here the mocked method will be called  
                                   // rather than the real one
    
  4. 如果这些选项不可行,那么您必须通过派生类测试该功能,或使用其他模拟框架,如TypeMock Isolator,Moles或JustMock。

答案 1 :(得分:3)

是的,这是Moq的一个非常基本的场景 假设你的抽象类看起来像这样:

public class MyClass : AbstractBaseClass
{
    public override int Foo()
    {
        return 1;
    }
}

你可以写下面的测试:

[Test]
public void MoqTest()
{
    var mock = new Moq.Mock<AbstractBaseClass>();            
    // set the behavior of mocked methods
    mock.Setup(abs => abs.Foo()).Returns(5);

    // getting an instance of the class
    var abstractBaseClass = mock.Object;
    // Asseting it actually works :)
    Assert.AreEqual(5, abstractBaseClass.Foo());
}