开发者

How to create Mock for the abstract base class using MOQ framework?

开发者 https://www.devze.com 2023-03-08 06:31 出处:网络
I want to write unit tests for MyClass but its base class is an abstract class. public class MyClass : AbstractBaseClass

I want to write unit tests for MyClass but its base class is an abstract class.

public class MyClass : AbstractBaseClass
{
}

I want to Mock the AbstractBase class, so that I can skip some of the logic in its constructor when I create the MyClass instance I want to test. Is th开发者_开发知识库ere anyway I can do this?

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


By inheriting from the base class you are extending it. It is more about getting your code into a testable state rather than having Moq work for you.

  1. You can either use composition instead of a base class and then use dependency injection (via an interface) that you can mock.
  2. Or if you have to inherit then extract the logic that you don't want to run into another class that you inject again via dependency injection.
  3. Or have that logic that you don't want to run be part of a virtual method that you can mock. (like @Ohad Horesh's answer:)

    public virtual void DoSomethingElse();
    
    mock.Setup(abs => abs.Foo());  //here the mocked method will be called  
                                   // rather than the real one
    

If these options are not viable then you will either have to test that functionality through the derived class or use another mocking framework such as TypeMock Isolator, Moles or JustMock.


Yes this is a pretty basic scenario in Moq.
Assuming your abstract class looks like this:

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

You can write the test below:

[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());
}
0

精彩评论

暂无评论...
验证码 换一张
取 消