Ryu*_*Ryu 5 c# unit-testing ninject inversion-of-control
我只是想知道在内核中重新绑定绑定的最佳做法是什么.
我有一个带有内核的类和一个带有默认生产绑定的私有类模块.
对于测试,我想覆盖这些绑定,以便我可以交换我的Test Doubles/Mocks对象.
不
MyClass.Kernel.Load(new InlineModule(m=> m.Bind<IDepend>().To<TestDoubleDepend>()))
Run Code Online (Sandbox Code Playgroud)
覆盖IDepend的任何现有绑定?
我尝试尽可能少地直接在我的代码中使用DI内核,而是依赖于构造函数注入(或者在特定情况下的属性,例如Attribute类).但是,我必须使用抽象层,以便我可以设置DI内核对象,使其在单元测试中可模拟.
例如:
public interface IDependencyResolver : IDisposable
{
T GetImplementationOf<T>();
}
public static class DependencyResolver
{
private static IDependencyResolver s_resolver;
public static T GetImplementationOf<T>()
{
return s_resolver.GetImplementationOf<T>();
}
public static void RegisterResolver( IDependencyResolver resolver )
{
s_resolver = resolver;
}
public static void DisposeResolver()
{
s_resolver.Dispose();
}
}
Run Code Online (Sandbox Code Playgroud)
使用这样的模式,您可以IDependencyResolver通过调用RegisterResolvermock或false实现来设置单元测试,该实现返回您想要的任何对象,而无需连接完整模块.如果您将来选择切换到另一个容器,它还具有从特定IoC容器中抽象代码的第二个好处.
当然,您还需要根据需要添加其他方法IDependencyResolver,我只是将这里的基础知识作为示例.是的,这将要求您在Ninject内核周围编写一个超级简单的包装器,它也可以实现IDependencyResolver.
你想要这样做的原因是你的单元测试应该只测试一件事,并且通过使用你的实际IoC容器,你实际上比一个被测试的类更多地运动,这可能导致错误的负面因素,使你的测试脆弱和(更重要的是)随着时间推移开发人员对其准确性的信心.这可能导致测试冷漠和放弃,因为测试失败但软件仍然可以正常工作("不要担心,一个总是失败,这不是什么大不了的事").