【问题标题】:Override Ninject binding locally inside a test method to bind mock objects在测试方法中本地覆盖 Ninject 绑定以绑定模拟对象
【发布时间】:2011-11-22 19:51:04
【问题描述】:

我有以下问题,我想在我的单元测试中使用 Ninject。 我对此的想法是这样的:

1) 在模块内定义一个全局绑定模式,以绑定我在测试中使用的假对象

2) 当使用模拟对象时,将其绑定到本地测试中

我没有找到一种在本地覆盖绑定配置的方法,我的想法是我在本地创建一个具有期望的模拟对象,并且我希望 kernel.Get() 方法返回一个具有所有绑定的对象,除了每个测试都在具有预期的测试中添加了一个本地模拟对象,这对我来说是可读和可维护的,因为我每个测试只覆盖 1 个绑定,这些对象是模拟的,因此它们不能在模块内部配置为测试上下文未知

我怎样才能做到这一点,我正在使用 c# 和 nunit。 如果我的方法有误,我想听听正确的方法。

【问题讨论】:

    标签: unit-testing mocking nunit ninject


    【解决方案1】:

    您不应该使用您的 IoC 容器来创建要在单元测试中测试的对象。而是使用new 手动创建它,并为每个构造函数参数传递一个模拟/存根对象。

    【讨论】:

    • 如果您正在测试的是 DI 绑定的有效性,并且您需要覆盖一个失败的绑定,除非它在应用程序环境中(例如,绑定到将查找的配置服务配置文件)?
    • 或者测试拦截。 (继续 Carl G 的评论)
    • 我个人认为单元/集成测试的混合方法是最好的。在测试特定实现时使用“new”,并使用 IoC 容器(与主项目相同)来测试“接口”项。这使您可以使用与“现实生活”中相同的容器来验证您的具体实现以及整个系统。
    • 我认为对于集成测试,您应该真正使用您原来的 IoC 容器。对于类级别的“原子单元测试”,自动模拟是要走的路,恕我直言。
    【解决方案2】:

    我有同样的问题,我知道这不是好方法,但在我这边,我会进行集成测试;不是单元测试。

    这是我的解决方案:

    Kernel.Rebind<TypeToBind>().ToConstant(Mock.Object);
    

    其中 Kernel 是您用来创建绑定的对象。 TypeToBind 是您要注入依赖项的类型。 Mock.Object 是您之前设置的对象。

    再次,我知道这不是很酷,但是在处理难以插入单元测试的遗留代码时,这可能是拥有良好安全网的一种拯救。

    【讨论】:

    • 我认为自己做这样的事情是完全可以的,我们所有的测试都这样做。事实上,Java 中的 AtUnit 是为了纯粹使用 DI 框架进行单元测试而发明的;)。
    【解决方案3】:

    我认为使用 IoC 框架进行测试是完美的方法。事实上,这就是为什么 IoC 首先存在,然后框架出现的原因。 Guice(谷歌的 java 注入 DI 框架)实际上支持此功能,您可以通过生产绑定传入模块,然后传入可以使用模拟对象覆盖某些绑定的 TestModule,然后您可以进行测试。我们一直在这样做,并且在 java 中很长一段时间以来它已经非常干净了。我刚刚进入自己,试图让我的测试重新绑定东西,但保留其余的绑定....

    还有像 AtUnit 这样的框架,您应该在其中使用 DI 框架来测试对象,而根本不使用 new 关键字。(不幸的是,我还没有看到该框架移植到 C# 领域: ( )。

    注意:这是可取的,因为当人们在生产模块中添加新绑定,然后在我的一个测试类系统中使用它时,它不会因空指针异常而失败,因为接口未在测试中绑定.人们不断添加,测试继续工作。在我看来,你现在应该只在 dtos 中使用关键字“new”,并且所有的 biz 逻辑都应该与 DI 连接起来,这样可以很容易地现在或以后很容易地添加测试(尽管我喜欢我自己先添加测试)。

    【讨论】:

      猜你喜欢
      • 2012-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多