几个星期前,我跳上MEF(ComponentModel()的行列,并且到现在使用对很多我的插件,也共用图书馆。总体而言,它已经很大,除了频繁的错误,我的一部分,其结果令人沮丧的调试届会议。

无论如何,我的应用程序已运行的巨大的,但我MEF相关代码变化已经引起我的自动生成至失败。我的多数单元的测试都失败,只是因为该模块是我的测试都取决于其他的模块,该模块所需要加载过MEF。我的工作围绕这些情况下绕过MEF和直接的实例,这些对象。

换句话说,通过MEF我会喜欢的东西

[Import]
public ICandyInterface ci { get; set; }

[Export(typeof(ICandyInterface))]
public class MyCandy : ICandyInterface
{
    [ImportingConstructor]
    public MyCandy( [Import("name_param")] string name) {}
    ...
}

但在我的单元的测试,我只想使用

CandyInterface MyCandy = new CandyInterface( "Godiva");

此外,CandyInterface需要一个数据库的连接,这是我的工作围绕由增加一个测试数据库以我单元的测试文件夹,我有关使用,为所有的测试。

好吧,这是我的问题关于这个情况:

  1. 这是一个不好的方式做事吗?
  2. 你会推荐的构成部分在[设定]
  3. 我还没有学会如何使用嘲笑单位测试--这是一个很好的例的情况下,我可能想要拟的基础的数据库连接(以某种方式),以刚刚返回的虚拟数据并不真的需要一个数据库?
  4. 如果你遇到这样的事情之前你能提供你的经验和你的方式解决你的问题吗?(或应该进入社区维基?)
有帮助吗?

解决方案

这听起来就像你是在正确的轨道。一个单元的测试,该测试 单元, 和你这么做的时候你直接创造的实例。如果你让MEF组成情况为你,他们会倾向于 一体化试验.不是有什么错误的集成试验,但单元的测试,往往更容易维护,因为你测试的各个单元中的隔离。

你不需要一个容器的电线了情况单元的测试.

我一般建议针对创作装置的安装,因为它导致的 一般具 反模式。

这是最好的做法来替代依赖 测试的双打.动态的模拟是一个更灵活的方式这样做的,所以肯定有些东西你应该学习的。

其他提示

我同意,创建文档手是远远好于使用MEF组合容器,以满足进口的,但是关于注意到'合成固定装置的安装导致一般具反模式'-我想说这不是总是这种情况。

如果您使用的是静态的容器和满足进口通过CompositionInitializer.SatisfyImports你将要面对的一般具反模式作为CompositionInitializer.初始化不能被称为超过一次。但是,你总是可以创造CompositionContainer,增加目录,并呼吁SatisyImportOnce在容器本身。在这种情况下可以使用一个新的CompositionContainer在每一个测试,并摆脱所面临的共用/一般具反模式

我在博客上如何做到的单元测试(不关,但只是相同)与MEF。该法是使用一个MockExportProvider和我创建了一个试验基于我所有的测试,以继承。

这是我的主要自动装配功能工作整合和单元的测试:

protected void AutoWire(MockExportProvider mocksProvider, params Assembly[] assemblies){

CompositionContainer container = null;

var assCatalogs = new List<AssemblyCatalog>();

foreach(var a in assemblies)
{
    assCatalogs.Add(new AssemblyCatalog(a));
}

if (mocksProvider != null)
{
    var providers = new List<ExportProvider>();

    providers.Add(mocksProvider); //need to use the mocks provider before the assembly ones            

    foreach (var ac in assCatalogs)
    {
        var assemblyProvider = new CatalogExportProvider(ac);                    
        providers.Add(assemblyProvider);
    }

    container = new CompositionContainer(providers.ToArray());

    foreach (var p in providers) //must set the source provider for CatalogExportProvider back to the container (kinda stupid but apparently no way around this)
    {
        if (p is CatalogExportProvider)
        {
            ((CatalogExportProvider)p).SourceProvider = container;
        }
    }
}
else
{
    container = new CompositionContainer(new AggregateCatalog(assCatalogs));
}

container.ComposeParts(this);        
}

更多信息在我的员额: https://yoavniran.wordpress.com/2012/10/18/unit-testing-wcf-and-mef/

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top