48

这看起来应该非常简单;然而,经过两个小时的阅读和试​​错没有成功,我认输并问你们!

我正在尝试将MochaShould.js一起使用来测试一些 JavaScript 函数,但我遇到了范围界定问题。我已将其简化为最基本的测试用例,但我无法使其正常工作。

我有一个名为 的文件functions.js,其中仅包含以下内容:

function testFunction() {
    return 1;
}

我的tests.js(位于同一文件夹中)内容:

require('./functions.js')

describe('tests', function(){
    describe('testFunction', function(){
        it('should return 1', function(){
            testFunction().should.equal(1);
        })
    })
})

此测试失败并显示ReferenceError: testFunction is not defined.

我明白为什么,因为我发现的大多数示例要么将对象和函数附加到 Nodeglobal对象,要么使用导出它们module.exports——但是使用这两种方法中的任何一种都意味着我的函数代码会在标准浏览器情况下抛出错误,其中这些对象不存在。

那么如何在不使用特定于节点的语法的情况下访问在我的测试中单独的脚本文件中声明的独立函数呢?

4

3 回答 3

29

感谢这里的其他答案,我已经开始工作了。

但是没有提到的一件事——也许是因为它是 Noder 中的常识——你需要将require调用的结果分配给一个变量,以便在从测试套件中调用导出的函数时可以引用它。

这是我的完整代码,以供将来参考:

functions.js

function testFunction () {
    return 1;
}

// If we're running under Node, 
if(typeof exports !== 'undefined') {
    exports.testFunction = testFunction;
}

tests.js

var myCode = require('./functions')

describe('tests', function(){
    describe('testFunction', function(){
        it('should return 1', function(){
            // Call the exported function from the module
            myCode.testFunction().should.equal(1);
        })
    })
})
于 2012-04-18T12:34:47.387 回答
18
require('./functions.js')

这没有任何作用,因为您没有导出任何内容。您所期望的testFunction是全球可用,基本上与

global.testFunction = function() {
    return 1;
}

您只是无法绕过导出/全局机制。这是节点的设计方式。没有隐式的全局共享上下文(例如window在浏览器上)。模块中的每个“全局”变量都被困在它的上下文中。

你应该使用module.exports. 如果您打算与浏览器环境共享该文件,有一些方法可以使其兼容。要快速破解,只需window.module = {}; jQuery.extend(window, module.exports)在浏览器中或node.js 中执行if (typeof exports !== 'undefined'){ exports.testFunction = testFunction }

于 2012-04-18T06:54:27.110 回答
9

如果你想通过 require 使任何模块可用,你应该使用

module.exports

如你所知 ;)

如果您想通过这样做在 Node 和浏览器中使用模块,有一个解决方案

function testFunction() { /* code */ }

if (typeof exports !== 'undefined') {
   exports.testFunction = testFunction
}

通过这样做,您将能够在浏览器和节点环境中使用该文件

于 2012-04-18T06:55:13.720 回答