如何使用默认构造函数参数的Moq抽象类?

时间:2012-12-23 06:49:06

标签: c# unit-testing nunit moq

我想Moq是一个在它的构造函数中有默认参数的抽象类。这样我就可以测试默认设置,以及testnig特定值。例如(注意,这纯粹是一个示例类)

public abstract class AbstractClassToTest
  {
      private string _name;
      private int _someInt;
      private int _anotherInt;

      public AbstractClassToTest(string name, int someInt = 10, int anotherInt = 20)
      {
          _name = name;
          _someInt = someInt;
          _anotherInt = anotherInt;
      }
  }

并按如下方式设置Moq对象:

var act = new Mock<AbstractClassToTest>(MockBehavior.Loose, "namestring");

但这会引发错误......

Message "Can not instantiate proxy of class:
Test.AbstractClassToTest.
Could not find a constructor that would match given arguments:
System.String
Parameter name: constructorArguments"

如何创建moq对象并保持默认值?

Moq:v 4.0.10827.0

1 个答案:

答案 0 :(得分:2)

Moq不会模拟类类型,只会模拟接口。可能是因为即使是一个抽象类也可能有很多“具体”实现,并且有很多状态。

相反,制作自己的模拟课程:

class AbstractClassToTestMOCK : AbstractClassToTest
{
  internal AbstractClassToTestMOCK(string name, int someInt = 10, int anotherInt = 20)
    : base(name, someInt, anotherInt)
  {
  }
}

修改

我原来答案的第一段都错了。我已经验证可以模拟(非静态)类类型(必须是public,并且嵌套在其中的所有类/结构也必须是public,就像一个接口),前提是有问题的实例构造函数是publicprotected(或protected internal)。然后,您可以Setup virtualabstract的所有public(包括protected)方法(以及属性,索引器等)。

回到原来的问题,问题只是命名和可选参数是一种语法糖,反射不能很好地支持。

如果您被允许修改原始AbstractClassToTest,另一种解决此问题的策略是重载实例构造函数,即将其添加到原始类:< / p>

protected AbstractClassToTest(string name)
    : this(name, someInt: 10, anotherInt: 20)
{
}

在这种情况下,您可能会或可能不想保持(原始构造函数的)参数可选。

PS! abstract类的实例构造函数不应为public。请改用protected