c# - Ninject 内核绑定(bind)覆盖

标签 c# unit-testing inversion-of-control ninject

我只是想知道在内核中重新绑定(bind)绑定(bind)的最佳做法是什么。

我有一个带有内核的类和一个带有默认生产绑定(bind)的私有(private)类模块。

对于测试,我想覆盖这些绑定(bind),以便我可以交换我的测试替身/模拟对象。

MyClass.Kernel.Load(new InlineModule(m=> m.Bind<IDepend>().To<TestDoubleDepend>()))

覆盖 IDepend 的任何现有绑定(bind)?

最佳答案

我尝试尽可能少地在我的代码中直接使用 DI 内核,而不是依赖构造函数注入(inject)(或在某些情况下使用属性,例如 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();
    }
}

使用这样的模式,您可以从单元测试中设置 IDependencyResolver,方法是调用 RegisterResolver 并使用模拟或伪造的实现来返回您想要的任何对象,而无需连接完整的模块。如果您将来选择切换到另一个 IoC 容器,它还有一个从特定 IoC 容器中抽象代码的第二个好处。

当然,您还希望根据需要向 IDependencyResolver 添加其他方法,我只是将基本知识作为示例包含在这里。是的,这将需要您围绕 Ninject 内核编写一个 super 简单的包装器,它也实现了 IDependencyResolver

你想要这样做的原因是你的单元测试实际上应该只测试一件事并且通过使用你的实际 IoC 容器,你实际上比被测试的一个类要多,这可能会导致误报使您的测试变得脆弱,并且(更重要的是)随着时间的推移动摇开发人员对其准确性的信心。这可能导致测试冷漠和放弃,因为测试有可能失败但软件仍能正常工作(“别担心,那个总是失败,这没什么大不了的”)。

关于c# - Ninject 内核绑定(bind)覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1261357/

相关文章:

c# - Autofac - 如何在创建实例时获取类名

javascript - C# 相当于 LZMA-JS 压缩

unit-testing - 用于 http 处理程序测试的 Golang 模拟函数

asp.net-mvc - 使用 CaSTLe Windsor 在 ASP.NET MVC 中设置控制反转 (IoC)

Java Spring IOC 构造函数参数注入(inject)一个 List<Integer>

.net - 温莎城堡 : How do you add a call to a factory facility not in xml?

c# - 过时的属性导致属性被 XmlSerialization 忽略

c# - VisualStudio.Net 引用不起作用

ruby-on-rails - rails : How to test code in the lib/directory?

unit-testing - 如何在 Golang 测试文件中构建导入