我如何让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文件根本就没有加载。

所以你想要做的就是加载一个文件,以便设置顶级(“全局”)钩子(例如, beforeafter等)。 选项:

  1. 你可以以编程的方式使用摩卡,并以你想要的顺序给它提供文件。

  2. 列出其他文件之前,可以强制自己始终在命令行上指定助手文件。 (我不会这样做,但这是可能的。)

  3. 另一个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的子目录中,那么beforeafter钩子现在会触发两次。 另外,如果你在那里放置一个beforeEach钩子,它将在每一个testing之前触发,而不仅仅是那个目录中的testing。

无论如何,我知道这个post有点老,但希望这会帮助其他人有类似的问题。

在尝试了各种各样的事情之后,我想到了这个问题,让我的testing连接一次到数据库,然后再在我的models上运行一堆crudtesting。

然后,我发现摩卡准备解决了我的问题。

在你的helper.js文件中,你可以定义一个preparefunction。

 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)