当我传递数据类的类型(通过Moq.Object.GetType(),其中Moq是存根实例)时,我正试图使用Moq来存根一个我想通过Activator.CreateInstance动态创建的数据类,但我得到了System.MissingMethodException {"No parameterless constructor defined for this object."}
我做错了什么?我不想为了适应Moq而更改我的主题代码。
测试
private Test() ...
{
var recordStub = new Mock<IRecord>();
var record = recordStub.Object;
var recordDefinition = new RecordDefinition()
{ MappedRecordClassType = record.GetType(), ...
var newRecord = CreateDataRecord(recordDefinition);
...
}
主题
private IRecord CreateDataRecord(RecordDefinition recordDefinition)
{
var result = Activator.CreateInstance(recordDefinition.MappedRecordClassType)
as IRecord;
return result;
}
您正在创建record.GetType()
的实例,由于record = recordStub.Object
是Moq在运行时动态生成的对象,它在您的情况下实现了IRecord
,因此您实际上要做的是创建动态生成对象的实例,而Activator.CreateInstance()
似乎找不到不接受该类型参数的公共构造函数。现在我不知道你为什么要做你正在做的事情,但我从未见过有人使用这样的Mock,所以我认为你应该重新考虑你的测试。
在代码的某个地方,Moq试图实例化一个对象,该对象要么没有被模拟出来,要么直接作为类公开。无论哪种方式,所述对象都没有具有0个参数的公共构造函数。
您需要跟踪在测试中没有公共0参数构造函数的对象被调用的位置,并修复它或以其他方式解决它。
我在最近的一个项目中遇到了同样的事情,在大多数情况下,我们将对象作为类本身而不是接口来呈现。
我同意Sniffer的观点。你要做的是传入typeof IRecord
,然后要求Activator创建它的实例。但是,它是一个接口,所以你不能直接创建它的例子,你需要一个具体的类来实现这一点。
如果这个测试有价值,你需要做的就是创建一个老式的手写存根。。。也就是说,一个几乎为空的类,它只是实现IRecord
接口,并返回测试所需的值(没有实际工作)。
但是,实际上你所做的就是测试Activator.CreateInstance
是否可以找到该类型并创建它的实例,我同意Sniffer的观点,你基本上是在测试第三方代码。您可能不应该也不应该涵盖这种方法。