1

我想 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"

如何创建最小起订量对象并保持其默认值?

最小起订量:v 4.0.10827.0

4

1 回答 1

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所有virtual(包括abstract)方法(和属性、索引器等publicprotected

回到最初的问题,问题只是命名参数和可选参数是一种语法糖,没有得到很好的反射支持。

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

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

在这种情况下,您可能希望也可能不希望保留(原始构造函数的)参数可选。

PS!类的实例构造函数abstract不应该是public. 改为使用protected

于 2012-12-23T07:00:47.830 回答