我如何使用 IMyType [T] 的模拟对象来模拟托管扩展框架(MEF)导入 ExportFactory [IMyType [T]] 的过程(本身就是通用接口)?或者,通常,指定要由ExportFactory返回的实例,而不能单独使用构造函数创建实例吗?
据我所知,Moq无法直接创建模拟实例。我想要实现整个接口的替代方法,该接口可能更大并且会更改,而我不想更改测试。
我曾经发现一个非常复杂的ExportProvider代码,其中包含键值字符串,如果 ExportFactory [T] 的通用类型本身是通用的,则该代码将不起作用。
编辑: 事实证明,现有代码使用从type.FullName生成的合同名称字符串。这对于非泛型来说很好,但是泛型具有不同的名称语法。我使用的代码已经具有一个非常复杂的类,该类派生自ExportProvider并覆盖了一些原始方法,该方法允许Moq mock.Object实例由工厂返回。实际上总是相同的实例,而不是工厂。另请参见CodeReview上的以下问题:https://codereview.stackexchange.com/questions/208550/retrieve-generic-contract-names-for-managed-extensibility-framework
// actual generic type is meaningless here, but it is a generic interface
public interface IMyType<T>
{
string GetMessage();
}
public class FactoryImporter<T>
{
[Import]
ExportFactory<IMyType<T>> MyTypeFactory {get;set;}
}
public class Tester
{
public void TestFactoryImporter()
{
Func<IMyType<string>> createMockFunc = () =>
{
var mock = new Mock<IMyType<string>>();
mock.Setup(m => m.GetMessage()).Returns("I'm a mocked IMyType<string>");
return mock.Object;
}
var regBuilder = new RegistrationBuilder();
// pseudo-code, how to do this in reality?
regBuilder.ForType<IMyType<string>>().CreateInstance(createMockFunc);
var catalog = new AggregateCatalog();
var appCatalog = new ApplicationCatalog(regBuilder);
catalog.Catalogs.Add(appCatalog);
var container = new CompositionContainer(catalog);
var factoryImporter = new FactoryImporter<string>();
container.ComposeParts(factoryImporter);
Assert.AreEqual(
"I'm a mocked IMyType<string>",
factoryImporter.MyTypeFactory.GetExport().Value.GetMessage());
}
}