测试依赖MEF注入的非导出类

时间:2012-12-10 15:39:36

标签: c# silverlight prism mef

我正在使用MEF将我的对象组合在一起,并在测试一些未导出到MEF容器但依赖于MEF将属性注入到属性设置器中的类时遇到了问题。

例如,考虑以下两种视图模型

public class ViewModelA
{
    [Import]
    internal IAdmin AdminService
    {
        get;
        private set;
    }

    public ViewModelA()
    {
        CompositionInitializer.SatisfyImports(this);
    }

    //constructor for testing
    internal ViewModelA(IAdmin adminService)
    {
        this.AdminService = adminService;
    }

    public void DoSomething()
    {
        this.AdminService.SetCurrentWindow(new ViewModelB());
    }
}


public class ViewModelB 
{
    [Import]
    internal IAdmin AdminService
    {
        get;
        private set;
    }

    [Import]
    internal IAnotherService AnotherServiceService
    {
        get;
        private set;
    }

    public ViewModelB()
    {
        CompositionInitializer.SatisfyImports(this);
    }

    public void DoAnotherThing()
    {
        //Does something with the properties injected via MEF
    }

}

这些类不会导出到MEF容器,因此我依赖于调用CompositionInitializer.SatisfyImports(this)来强制导入依赖项。

我想为ViewModelA创建一个测试来检查对DoSomething的调用,导致IAdmin.SetCurrentWindow方法被一个ViewModelB实例调用一次。为了满足这个要求,我为ViewModelA创建了一个构造函数重载,它以IAdmin作为参数,我还使用Moq和Silverlight单元测试框架创建了以下测试。

    [TestMethod]
    public void DoSomethingStandard_CallsSetCurrentWindowWithViewModelB()
    {
        var adminServiceMock = new Mock<IAdmin>();
        var vmA = new ViewModelA(adminServiceMock.Object);
        vmA.DoSomething();
        adminServiceMock.Verify(ad => ad.SetCurrentWindow(It.IsAny<ViewModelB>()), Times.Exactly((1)));
    }

我的问题是,当测试运行时,对ViewModelA.DoSomething的调用实例化一个ViewModelB,而后者又会抛出一个

  

System.Reflection.ReflectionTypeLoadException:无法加载一个或多个请求的类型。检索LoaderExceptions属性以获取更多信息。

这是因为ViewModelB构造函数调用CompositionInitializer.SatisfyImports(this)但在我的测试项目中没有设置MEF容器。

有没有想过如何最好地测试这种情况?或者如何重新构建代码以使其可测试?

1 个答案:

答案 0 :(得分:1)

我认为您唯一能做的就是将[Import] ed属性更改为公共setter公开并直接设置实例。在单元测试中你不应该担心MEF。

这个thread更加深入。{/ p>