我应该单元测试一个具有MEF属性的类吗?

问题描述:

我想重构一个DLL来使它成为MEFable。我应该单元测试一个班级是否装饰有[导出]或[导入]和其他MEF属性?我应该单元测试一个具有MEF属性的类吗?

思考了几个小时后,再读一些TDD博客,我应该说,是的,我必须测试我的班级是否具有MEF属性。

所以我重构上课前我写那样的单元测试:

[TestClass] 
public class When_SampleClass_mefable 
{ 
    [TestMethod] 
    [TestCategory("LFF.Kabu.Win.Login.ViewModel.SampleClass")] 
    public void Should_SampleClass_be_marked_with_Export_Attibute() 
    { 
     //arrange 
     var info = (typeof (SampleClass)); 

     //act 
     var attr = info.GetCustomAttributes(true); 

     var hasExportAttribute = 
      attr.Where(x => x.GetType() == typeof (ExportAttribute)) 
       .Where(x => ((ExportAttribute)x).ContractType == typeof(SampleClass)) 
       .Count() > 0; 
     //assert 
     Assert.IsTrue(hasExportAttribute, "SampleClass is not marked with Export."); 
    } 
} 

对于其他MEF属性,如[ImportingConstructor]或[PartCreationPolicy]我做了同样的方式。

您的测试应该更多地关注目标而不是机制。创建验证,比如像“如果我在一个容器中抛出类型的X,Y和Z一起,那么我就可以从容器拉一个IFoo的接口”的测试中,像这样:

[Test] 
public void Can_get_IFoo_from_container_with_Foo_Bar_Baz() 
{ 
    var catalog = new TypeCatalog(typeof(Foo), typeof(Bar), typeof(Baz)); 
    using (var container = new CompositionContainer(catalog)) 
    { 
     var test = container.GetExportedValue<IFoo>(); 
    } 
} 

这不再是一个真正的“单元”测试,因为它涉及多个类和一个IoC容器。我们把它们称为“组合测试”。

+0

嗯,我想当我做单元测试,然后我只想知道我的班(单位)行为像预期。我真的不想测试它的组成,所以更多的MEF像预期的那样工作。对于我的一段代码,我只需要保证设置属性。如果在运行时组合不符合我的进口或出口,那么它不是我班(单位)的问题。你是否同意这一点? – blindmeis 2010-08-12 11:16:48

+0

@blindmeis:我不同意。 MEF属性是仅与集成相关的元数据。你正在试图将集成关注点放到单元测试中,这不适合。假设你在所有进口上改变合同类型,但忘记改变被测试的类的输出。您的单元测试不会检测到这一点:它将继续验证是否存在错误的导出属性。我的测试会检测到不匹配。 – 2010-08-12 12:41:59

+0

你对你的作文测试是正确的。但我看到我的单元测试就像它是一个单元测试。所以如果我改变合同,我做这种改变的单位将失败,它应该。但后来我知道这是正确的需求变化,所以我必须改变我的单元测试。我看到你的作文测试是必要的,但比单元测试的水平要高。顺便说一句,我只是做了测试,因为我试图学习tdd的方式。在那里我有要求,我的课应该是mefable。 – blindmeis 2010-08-12 16:26:09