我如何让Mocha加载一个helper.js文件来定义全局钩子或者实用程序?
我有一个名为test/helper.js
的文件,用于在我的Node.js应用程序上运行Mochatesting。 我的testing结构如下所示:
test/ test/helper.js # global before/after test/api/sometest.spec.js test/models/somemodel.spec.js ... more here
helper.js
文件必须被加载,因为它包含我的testing套件的全局钩子。 当我运行摩卡来执行整个testing套件时,像这样:
mocha --recursive test/
helper.js
文件在我的testingbefore
加载,并且我的before
钩子按预期执行。
但是,当我只运行一个特定的testing时, helper.js
不会在testing之前加载。 这是我如何运行它:
mocha test/api/sometest.spec.js
没有全球调用before
,甚至没有一个console.log('I WAS HERE');
。
那么如何让Mocha 始终加载我的helper.js
文件呢?
摩卡没有任何名为helper.js
的特殊文件的概念,它会加载其他文件之前。
当你运行mocha --recursive
时,你正在尝试做的工作 – 因为Mocha 正好加载你的文件的顺序而recursion。 由于helper.js
比其他文件高一级,因此首先加载。 当你指定一个单独的文件给摩卡时,摩卡只是加载这个文件 ,正如你发现的,你的helper.js
文件根本就没有加载。
所以你想要做的就是加载一个文件,以便设置顶级(“全局”)钩子(例如, before
, after
等)。 选项:
-
你可以以编程的方式使用摩卡,并以你想要的顺序给它提供文件。
-
列出其他文件之前,可以强制自己始终在命令行上指定助手文件。 (我不会这样做,但这是可能的。)
-
另一个select是像我在这个答案中详细说明的那样组织你的套件。 基本上,你有一个“顶级”文件,加载其余的套件。 使用这种方法,您将失去在单个文件上运行Mocha的能力,但您可以使用
--grep
来select正在运行的内容。
您不能使用-r
选项。 它在运行套件之前加载一个模块,但不幸的是,加载的模块不能访问任何Mocha提供给testing的testing接口,所以它不能设置钩子。
我所做的是创build一个test/test_helper.js
文件,该文件导出所有我创build的帮助器:
// test/test_helper.js module.exports = { MyHelper: require('./helpers/MyHelper') }
然后,我require
任何testing我需要帮助者使用它:
// test/spec/MySpec.js var helper = require('../test_helper'); // Or if you need just "MyHelper" var myHelper = require('../test_helper').MyHelper; describe('MySpec', function () { // Tests here... });
我更喜欢上面的方法,因为它容易理解和灵活。 你可以在我的演示中看到它的行动: https : //github.com/paulredmond/karma-browserify-demo/tree/master/test
首先,我肯定会使用mocha.opts
这样你就不必每次都包含你想要的选项。 正如所指出的,一个选项是使用--grep
,但我不是那个人的巨大粉丝。 它要求你用一种过于简单的方式来命名一切。 如果before
钩子不是asynchronous的,你可以在你的mocha.opts
使用mocha.opts
。 例如
#mocha.opts --recursive --require test/helpers.js
这听起来像这不会为你工作,因为你想全球after
钩。 我所做的是我每次都调用完整的testing套件,但是如果我正在研究中,只想testing一个套件,甚至是一个特定的testing,我使用排他性function, only
https:// mochajs .org /#独占testing 。 你可以把它it.only('...
或者describe.only('...
如果你这样做,它会查看所有的testing,并设置完全像你的完整testing工具,但是只执行testing或套件已经指定。
现在你可以包含这些全局钩子没问题。 @Louis提到你的helpers.js
只是按照正确的顺序加载。 那是不正确的。 如果将任何钩子放在describe
块之外,它将自动成为全局钩子。 这可以通过把它放在自己的文件中来完成
// helpers.js before(function() { console.log('testing...'); });
或者在一个testing文件中
// some.spec.js before(function() { console.log('testing...'); }); describe('Something', function() { it('will be tested', function() { ... }); });
显然,我认为把它放在自己的文件中是更清洁的。 (我把它叫做hooks.js
)。 要点是,这不是文件加载顺序的结果。
只是其中一个可能对其他人显而易见的问题,但是我并没有将它们放在一个describe
块中,而是简单地拼凑在一起。 它们不是目录特定的。 所以如果你将helpers.js
复制到testing的子目录中,那么before
和after
钩子现在会触发两次。 另外,如果你在那里放置一个beforeEach
钩子,它将在每一个testing之前触发,而不仅仅是那个目录中的testing。
无论如何,我知道这个post有点老,但希望这会帮助其他人有类似的问题。
在尝试了各种各样的事情之后,我想到了这个问题,让我的testing连接一次到数据库,然后再在我的models
上运行一堆crud
testing。
然后,我发现摩卡准备解决了我的问题。
在你的helper.js
文件中,你可以定义一个prepare
function。
prepare(done => { console.log('do something asynchronously here') done() }, done => { console.log('asynchronously clean up after here') done() })
作品一种享受。
在我们的项目中,我们使用的帮手有点像这样:
clientHelper = require("../../../utils/clientHelper")
您需要正确configuration助手的相对path。
然后像这样调用它:
clientHelper.setCompanyId(clientId)