【问题标题】:Dependency Loading & File System Mocking依赖加载和文件系统模拟
【发布时间】:2016-11-10 21:51:22
【问题描述】:

所以我有一个依赖:

dep = require('dep')

如果我在调用 dep 函数之前模拟出文件系统,则找不到导出 dep 的文件。

mockFs({})
dep.bar() #file where dep exported from not found

如果我在模拟导出 dep 的文件之前调用一个函数。

dep.foo()
mockFs({})
dep.bar() #works

有什么想法可以解释这种行为吗?

【问题讨论】:

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


    【解决方案1】:

    您的 require() 调用已缓存,因此 dep 使用的是真实文件系统,因为它可能调用了尚未模拟的 require('fs')

    稍后模拟fs 意味着对require('fs') 的任何 调用都将使用模拟,但已经加载的任何内容都不会受到影响。

    【讨论】:

    • 谢谢!有什么想法让它继续加载吗?如果事先调用 dep.foo() 似乎其他函数也会被加载
    • 关于单元测试和模拟,这是一个棘手的部分——文件的加载顺序!通常,所有require()s 都位于每个文件的顶部,因此所有这些依赖项都已加载,因为所有文件都首先加载,甚至在您的第一个测试文件(和第一个模拟)运行之前!一些模拟库有“间谍”,可以接管现有的功能,甚至是要求缓存。有时您可以更改调用 require() 的位置,以便有效地模拟它们。
    • 在调用上述场景 2 中的第二个函数时,我没有考虑到与未找到依赖项关联的文件方面的任何想法?在所有代码之前都需要依赖项。谢谢!
    • 我不知道那里有什么,抱歉。进行此类操作的一种方法是将需要模拟的对象作为变量存储在您可以访问的内容中。比如,如果很多逻辑都可以访问server 对象,他们可以从server.fs 调用文件系统,并且在您的测试运行之前,您模拟server.fs(之后将其设置回来)。