Moq MEF导入?

时间:2010-07-02 15:00:35

标签: c# silverlight moq mef

我有一个A类,其中包含以下内容:

public class A {
    [Import(typeof(IMyService)]
    public IMyService MyService { get; set; }

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

    public void DoWork() {
        //Blah
        MyService.DoIt();
        //Blah
    }
}

测试这个测试(单独的Dll - 显然)

[TestMethod]
public void TestDoWork() {
    //Blah
    DoWork();
    //Assert assert
}

这失败了,因为尝试调用'MyService'会给我null。 我接着试过了:

[ClassInitialize]
public void InitialiseClass() {
    var myService = new Mock<IMyService>();
    MyService = myService.Object;
}

将'MyService'声明为:

[Export(typeof(IMyService))]
public IMyService MyService { get; set; }

但仍然没有快乐,我错过了什么 - 这甚至可能吗?

我正在使用SL3,MEF Preview 9和MOQ。

任何帮助表示赞赏!

干杯

克里斯

3 个答案:

答案 0 :(得分:5)

你的课应该是这样的:

public class A 
{
    private readonly IMyService _myService;

    [ImportingConstructor]
    public A(IMyService myService)
    {
        _myService = myService;
    }

    public void DoWork() {
        //Blah
        _myService.DoIt();
        //Blah
    }
}

你的测试应该是这样的:

[TestMethod]
public void DoWork_invokes_IMyService_DoIt() 
{
    // arrange mock and system under test
    var myService = new Mock<IMyService>();
    var a = new A(myService.Object);

    // act    
    a.DoWork();

    // assert that DoIt() was invoked
    myService.Verify(x => x.DoIt());
}

使用MEF的事实在单元测试中不重要。 MEF仅在将多个组件连接在一起时才起作用,这与单元测试中发生的情况完全相反。根据定义,单元测试是对组件进行单独测试。

编辑:如果您更喜欢属性注入,那么您的类不需要构造函数,而单元测试中的安排部分应该是这样的:

    var myService = new Mock<IMyService>();
    var a = new A();
    a.MyService = myService.Object;

答案 1 :(得分:1)

如果您已将[导出]添加到IMyService实例,您是否已将其实际添加到合成容器中?如果没有,它将不参与作文。要将模拟对象添加到容器,请执行以下操作:

 container.ComposeExportedValue<IMyService>(mock.Object);

或者只是:

container.ComposeExportedValue(mock.Object); // type inference.

在创建A实例之前执行此操作将使其能够在A实例中编写。

答案 2 :(得分:0)

你不应该在单元测试中启动MEF。组合超出了单元测试的范围,与IoC容器没有什么不同。

Insted,您应该手动注入所需的依赖项:

[TestClass]
public class ATest {
  Mock<IMyService> myService ;
  [TestInitialize]
  public void InitialiseClass() {
    myService = new Mock<IMyService>();
  }

  [TestMethod]
  public void DoWorkShouldCallDoIt {
    A a = new A();
    a.MyService = myService.Object;
    a.DoWork();
    myService.Verify(m=>m.DoIt(), Times.Once());
  }
}