【问题标题】:Mock node.js modules模拟 node.js 模块
【发布时间】:2013-07-03 07:55:37
【问题描述】:

假设我有这种情况(架构)

layer1 -> layer2 -> layer3

层只是普通的 node.js 模块(有一些导出的功能)

Layer1 需要 layer2 并调用他的函数,而 layer2 需要 layer3 并调用他的函数。

我想测试 layer1 中的函数,但也要模拟 layer3(我在 layer1 中的函数调用被传播到 layer3 并且我想模拟这个)。

最好的方法是什么? 我看过这个模块:https://github.com/thlorenz/proxyquire,但我认为它不支持像我的示例那样深入到 2 级或更高级别时进行模拟。

感谢您的任何建议!

【问题讨论】:

  • 为什么你认为 proxyquire 不能在 3 层深的地方工作?
  • 正如我在文档和我的示例中看到的那样,您必须拥有该模拟模块的实例 (var foo = proxyquire('./foo', { 'path': pathStub });) .. .但我无法从我的测试中进入那个layer3模块,因为我没有测试他......如果你有一些例子(源代码或伪代码)请写出来:)
  • layer2 是否需要 layer3 像这样:require('module3') 或 require('./module3')?
  • 在 NodeJS 中模拟模块有时真的很棘手,因为它很容易陷入依赖地狱。我建议您尝试将您的模块与 DI 微框架松散地绑定,例如 c9-architect。我发现一旦开始以这种方式组织代码,测试代码就容易多了,并且从 npm 安装的节点模块可以通过使用 选项参数。
  • AndyD:它是 require('./module3')。模块不在 package.json 中,而只在我的代码中,所以它是它们的相对路径。

标签: javascript node.js unit-testing mocking integration-testing


【解决方案1】:

我使用mockery 取得了巨大的成功,尽管根据您要模拟的内容,它可能会变得非常乏味。

但是,您的设置似乎有点古怪。如果你想对第 1 层进行单元测试,你应该只需要模拟第 2 层,并且第 1 层和第 3 层之间不应该有任何(直接)连接。

【讨论】:

  • 我们实际上是在做集成测试。查看我对自己问题的回答,有问题解释。
【解决方案2】:

实际上我错了 proxyquire。是的,您可以在您正在测试的原始模块下方 2 或更多深度模拟某些模块,并且它可以正常工作,正如他们在示例中显示的那样。只需将存根与您正在模拟的模块的路径放在一起。如果你在模拟 layer3,stub 的路径必须与 layer2 中写入的 layer3 的路径相同(所以它是相对于 layer2,而不是 layer1 或某个根)。

我们正在进行集成测试,这很困难,因为我们使用的是 mongoDB 数据库,并且没有用于 mongo 的嵌入式数据库。有一些尝试和替代方案,但正如我所见,它们还不够好。所以这是我的问题的根源,我们不得不模拟整个数据层。

在此之前,我们在某些机器上拥有真实数据库,而 CI 服务器 (Jenkins) 上的集成测试使用的是真实数据库,但这并不是很好,因为您无法在笔记本电脑上运行测试。

因此,模拟应用程序的整个数据层也是非常糟糕的解决方案,但正如我所见,没有其他选择。如果有人有相同或相似的情况,请随时在此处编写您的解决方案。

【讨论】:

    猜你喜欢
    • 2014-06-14
    • 2016-05-10
    • 1970-01-01
    • 2014-04-06
    • 2014-01-09
    • 2012-03-22
    • 2011-12-06
    • 2021-08-21
    • 2021-11-18
    相关资源
    最近更新 更多