如何使用MOQ框架为抽象基类创建模拟?
我想为MyClass编写单元测试,但其基类是一个抽象类。如何使用MOQ框架为抽象基类创建模拟?
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.
}
}
通过从正在扩展它的基类继承。更重要的是让你的代码进入可测试状态,而不是让Moq为你工作。
- 您可以使用组合而不是基类,然后使用可以模拟的依赖注入(通过接口)。
- 或者如果您必须继承,那么将您不想运行的逻辑提取到另一个通过依赖注入再次注入的类中。
-
或者让你不想运行的逻辑是你可以模拟的虚拟方法的一部分。 (如@Ohad Horesh的答案:)
public virtual void DoSomethingElse(); mock.Setup(abs => abs.Foo()); //here the mocked method will be called // rather than the real one
如果这些选项是不可行的,那么你将不得不通过派生类来测试该功能,或使用其他模拟框架,如TypeMock隔离,痣或JustMock 。
是的这是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());
}
不,我认为我没有正确解释它......其实我不想单元测试抽象类本身.. – Dexterslab 2011-05-23 19:44:03
请注意, Foo()必须在AbstractBaseClass的定义中标记为虚拟 – 2013-08-26 10:11:20
您有设计问题。 AbstractClass是在其ctor中对一个依赖项进行硬编码的实例化。如果此依赖关系上的方法是您想要模拟的,则需要更改AbstractClass ctor以获取依赖关系。如果你可以详细说明这种方法在内部做什么,也许你会得到一些更好的答案 – Gishu 2011-05-26 08:48:05