模拟 node.js 模块

6
假设我有这样的情况(架构):
layer1 -> layer2 -> layer3

层级只是普通的node.js模块(有一些被导出的函数)。
Layer1需要Layer2并调用它的函数,而Layer2需要Layer3并调用它的函数。
我想测试Layer1中的函数,但也想mock Layer3(我的函数调用在Layer1中传播到Layer3,我想mock这个)。
最好的方法是什么? 我看了这个模块:https://github.com/thlorenz/proxyquire,但我不认为它支持像我的例子那样深度为2或更多层次的mocking。
感谢任何建议!

为什么您认为 Proxyquire 无法在三层深度下工作? - AndyD
根据文档和我的示例,您必须拥有该模拟模块的实例(var foo = proxyquire('./foo', { 'path': pathStub });) ... 但是我无法从我的测试中访问该layer3模块,因为我不测试它... 如果您有一些示例(源代码或伪代码),请写下来 :) - Ivan Longin
层2是否需要像这样的层3:require('module3')还是require('./module3')? - AndyD
1
在NodeJS中模拟模块有时可能会非常棘手,因为它很容易陷入依赖地狱。我建议您尝试使用c9-architect等DI微框架来松散绑定您的模块。一旦按照这种方式组织代码,我发现测试代码变得更加容易,并且可以通过使用“选项”参数将从npm安装的节点模块注入到您的代码中,而无需显式要求。 - Naor Biton
AndyD:需要使用require('./module3')。模块不在package.json中,而是在我的代码中,因此它们的路径是相对的。 - Ivan Longin
显示剩余3条评论
2个回答

1
我曾经成功地使用mockery,但具体取决于你想要模拟的内容,可能会变得非常繁琐。
然而,你的设置似乎有些奇怪。如果你想对第一层进行单元测试,你只需要模拟第二层,并且第一层和第三层之间不应该有任何(直接)连接。

我们正在进行集成测试。请看我对自己问题的回答,里面有问题的解释。 - Ivan Longin

1
实际上,我在使用proxyquire时有些错误。是的,你可以模拟测试中原始模块下2个或更多深度的某些模块,并且它能像他们展示的那样正常工作。只需将存根放置在您正在模拟的模块的路径中。如果您正在模拟layer3,则存根的路径必须与在layer2中编写的layer3的路径相同(因此它是相对于layer2而不是layer1或某个根目录)。
我们正在进行集成测试,但由于我们正在使用mongoDB数据库,所以这很困难,因为没有嵌入式数据库可用于mongo。有一些尝试和替代方案,但据我所见,它们都不太好。因此,我的问题的根源在于我们必须模拟整个数据层。
在那之前,我们在某台机器上有一个真实的数据库,CI服务器(Jenkins)上的集成测试使用该真实数据库,但这并不是很好,因为例如您无法在笔记本电脑上运行测试。
因此,模拟应用程序的整个数据层也是非常糟糕的解决方案,但据我所见,没有其他选择。如果有人遇到了相同或类似的情况,请随意在此处编写您的解决方案。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接