我有一个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。
任何帮助表示赞赏!
干杯
克里斯
答案 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());
}
}