如何使用Moq实例模拟MEF ExportFactory <tgeneric>?

时间:2018-11-19 15:50:59

标签: c# .net moq mef

我如何使用 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());
    }
}

0 个答案:

没有答案