2014-09-10 34 views
1

使用Ninject,我有以下,并希望利用FluentAssertions测试:如何测试我的工厂是否正确绑定?

[Test] 
public void InterfacesEndingWithFactoryShouldBeBoundAsFactories() { 
    // Given 
    IKernel kernel = new StandardKernel(); 
    kernel.Bind(services => services 
     .From(AppDomain.CurrentDomain 
      .GetAssemblies() 
      .Where(a => !a.FullName.Contains("Tests"))) 
     .SelectAllInterfaces() 
     .EndingWith("Factory") 
     .BindToFactory() 
    ); 

    // When 
    var factory = kernel.Get<ICustomerManagementPresenterFactory>(); 

    // Then 
    factory.Should().NotBeNull(); 
} 

有没有什么好的方法来测试是否工厂实际上是正确绑定?

+0

对于任何SO社区成员,我已接受@KevinKuszyk答案,因为他提供了一种方法来执行我所要求的操作。此外,还应该考虑BatteryBackupUnit的答案,因为它也非常有启发性。两个答案都很有意义。 – 2014-12-05 14:15:34

回答

2

我的流利的断言来测试我的Ninject绑定写了extension package。使用它,您的测试可以改写这样的:

[Test] 
public void InterfacesEndingWithFactoryShouldBeBoundAsFactories() { 
    // Given 
    IKernel kernel = new StandardKernel(); 
    kernel.Bind(services => services 
     .From(AppDomain.CurrentDomain 
      .GetAssemblies() 
      .Where(a => !a.FullName.Contains("Tests"))) 
     .SelectAllInterfaces() 
     .EndingWith("Factory") 
     .BindToFactory() 
    ); 

    // When 


    // Then 
    kernel.Should().Resolve<ICustomerManagementPresenterFactory>().WithSingleInstance() 
} 

至于建议的@Will Marcouiller,我还要提取代码来引导内核到它自己的类,以便它可以在你的应用程序的组成根和被调用你的单元测试。

+0

是它可以作为一个NuGet包 – 2014-09-11 15:52:22

+0

是的,你可以在这里:?!http://www.nuget.org/packages/FluentAssertions.Ioc.Ninject – 2014-09-11 16:25:00

+0

尼斯一个刚试过我喜欢它,谢谢你的提示,我不能超过一次upvotemore因为我= d – 2014-09-11 16:47:07

1

首先,没有ninject的基础设施,以测试哪些类型受到影响,这不是。由于流畅的语法,单元测试非常复杂,并且调用方法时会返回许多接口。所以你所能做的就是集成测试。现在

,在我看来,该From(...)是有问题的。如果您想创建一个组件,你可以代替你传递给From的组件,创建一个包含几种类型的额外的测试组件,然后测试是否可以说interface IFoo不绑定,interface IFooFactory必然,class Foo不绑定,..你会有一个功能齐全的测试。

但是,请考虑如果没有IFooFactorySomeClass的绑定使用IFooFactory作为构造函数参数,ninject将引发异常。现在如果你有一个composition root,简单地启动应用程序会告诉你是否存在必要的绑定。

该测试比工厂常规集成测试更有用。考虑一下,如果有人意外绑定了工厂,也是手动的。这不会在约定集成测试中显示出来,但是启动应用程序后,ninject会抛出一个异常,指出这个接口有多个绑定。

+0

事实上,我注意到我需要为这个约定指定一个'Where(a => a.FullName.Contains(“MyProject”)',否则它将所有其他类型的.NET Framework 。我还努力遵循Mark Seemann的指导原则,在CompositionRoot上写得非常好,我甚至写了一个'CompositionRoot'类,我根据我使用的约定编写了对象图,我简单地调用了'CompositionRoot.ComposeObjectGraph ()'在我的程序启动 – 2014-09-11 11:59:43