12

我有很多时间尝试使用 Mocha 和 RequireJS 设置 node/npm。这就是我所做的。

我创建了一个 testing/ 目录,结构如下:

testing/
   |
   +-- package.json
   |
   +-- README.md
   |
   +-- test/
         |
         +-- mocha.opts
         |
         +-- widgets/
                |
                +--mywidget/
                       |
                       +-- test.js

以下是每个相关文件包含的内容:

包.json:

{
    "name":"testing-project",
    "version":"2.5.0",
    "description":"Testing Project",
    "keywords":["test"],
    "engines": { "node": ">= 0.7.0 < 0.11.0" },
    "scripts" : {
        "test": "./node_modules/.bin/mocha"
    },
    "devDependencies": {
        "mocha": ">= 1.18.2",
        "requirejs": ">= 2.1.11",
        "should": ">= 3.2.0",
        "expect.js": ">= 0.3.1"
    }
}

测试/mocha.opts:

--require expect.js
--require should
--require requirejs
--require mocha
--reporter spec
--ui tdd
--recursive
--growl

测试/小部件/mywidget/test.js

'use strict';
var requirejs = require('requirejs');
// Also tried with:  require('../../../r.js')  which I downloaded from RequireJS' site

requirejs.config({
    baseUrl: '../../../../',
    nodeRequire: require
});

console.log('before require');
requirejs(['mywidget/trunk/src/mywidgetfile.js'], function(myObj){
    console.log('after require');

    var expect = require('expect.js');

    // Instead of the above "requirejs['mywidget..." line, I've also tried:
    // var myObj = requirejs('mywidget/trunk/src/mywidgetfile.js');   AND:
    // var myObj = requirejs('../../../../mywidget/trunk/src/mywidgetfile.js');

    describe('My Widget', function(){
        describe('my-widget#getInfo', function(){

            it('should pass this test', function(done){
                expect( myObj.returnString('test') ).to.equal( 'test' );

                done();
            })
        })
    });
});
console.log('done');

它将在“需要之前”和“完成”输出控制台行,但只要我有 requirejs(['mywidget... 行,它就不会命中 after require。如果我删除 requirejs 行(和相应的右括号/括号行),而是使用直接“var myObj =”行,我得到“找不到模块”,如果我使用第二个“var myObj”行,我得到“参考错误:未定义定义”。

为了方便其他开发人员,我正在尝试使用 npm 打包这一切,以便我从顶部的“testing/”目录中运行命令“npm test”。

我一直在寻找答案并尝试了很多事情,但我似乎不需要使用 RequireJS 的文件并定义了“define()”。我可以执行测试,这不是问题......它只是试图将 RequireJS 插入到我开始遇到问题的组合中。

任何帮助都将是巨大的!

谢谢!

4

1 回答 1

11

您向我们展示的内容存在多个问题。您错误地使用了 RequireJS 和 Mocha。

要求JS

我很确定你baseUrl是不正确的。您似乎认为 Mocha 的当前工作目录将设置为test/widgets/mywidget/test/widgets/mywidget/test.js. 事实并非如此。工作目录是你运行时碰巧在的任何地方npm test。根据您的描述,您在testing/运行它时处于其中。我不清楚你baseUrl应该有什么价值,因为你没有在你的问题中提供足够的信息,但我相信从我刚刚给出的解释中你可以弄清楚。

现在你可能会想“当然,mybaseUrl是正确的,因为当我执行时requirejs(['mywidget/trunk/src/mywidgetfile.js'], function(myObj){我没有收到错误”。这将是一个错误的推论。虽然此requirejs调用安排了模块的加载,但 RequireJS 没有机会尝试加载它,因为 Mocha 在 RequireJS 尝试加载它之前就退出了。您可以通过将模块路径替换为完全垃圾来检查这一点,并且不会出现错误。

解决此baseUrl问题后,使用var myObj = requirejs('mywidget/trunk/src/mywidgetfile.js')将按预期工作。因此,您将能够避免使用的异步形式require(这是使用依赖项数组作为第一个参数的形式)。(requirejs您使用的函数只是requireRequireJS 文档中通常调用的函数的别名。)

摩卡

您的测试没有运行,因为 Mocha 没有看到它们。Mocha 的工作方式是读取它找到的所有测试文件,然后执行它们。每个describe调用的回调都会立即执行,每个it调用的回调都会记录为要运行的测试。一旦 Mocha 确定存在哪些测试,它就会运行它们。

您的测试文件发生的情况是 Mocha 像往常一样执行它。但是,没有对测试文件的调用describeit在测试文件的顶级范围内调用。您的回调中有调用,requirejs但请记住我上面所说的:RequireJS 没有机会加载模块,因此它没有机会运行回调。(即使它确实运行了,也为时已晚。)所以 Mocha 没有看到任何测试并立即退出。

前进的道路

找出baseUrl你需要的,然后这应该工作:

'use strict';
var requirejs = require('requirejs');

requirejs.config({
    baseUrl: <whatever value is needed here>,
    nodeRequire: require
});

var myObj = requirejs('mywidget/trunk/src/mywidgetfile.js');

describe('My Widget', function() {
// etc...

你也可以考虑完全从你的测试套件中删除 RequireJS。我编写了一个在 Node 中和在浏览器中一样好用的库。它由 AMD 模块组成,由浏览器中的 RequireJS 加载,但我在测试套件中没有使用 RequireJS。这是我用来在 Node.js 中加载我的模块的加载器。还有一个我没有使用但应该提供类似功能的amdefine 。

于 2014-04-02T22:24:05.520 回答