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.
- You can either use composition instead of a base class and then use dependency injection (via an interface) that you can mock.
- 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.
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());
}
精彩评论