如何使用 Mocha 测试“正常”(非节点特定)JavaScript 函数?

Posted

技术标签:

【中文标题】如何使用 Mocha 测试“正常”(非节点特定)JavaScript 函数?【英文标题】:How do I test 'normal' (non-Node specific) JavaScript functions with Mocha? 【发布时间】:2012-04-29 13:08:35 【问题描述】:

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

我正在尝试使用 Mocha 和 Should.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

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

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

【问题讨论】:

你在你的functions.js中使用exports.testFunction = testFunction了吗? 不,显示functions.js的全部内容。请再读一遍这个问题——我特别声明我不想想在源文件中使用节点特定的语法。 【参考方案1】:
require('./functions.js')

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

基本相同
global.testFunction = function() 
    return 1;

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

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

【讨论】:

好的,有道理,谢谢。那么 Mocha 不是真的用于测试非 Node JS 吗?在我遇到的任何文档或教程中都没有提到这一点。 您可能想尝试使用 Qunit (docs.jquery.com/Qunit) 在浏览器上进行测试,或者尝试使用zombie.js (github.com/assaf/zombie) 在 mocha 中模拟浏览器环境。 @MarkBell Mocha 在浏览器中应该可以正常工作,在这种情况下您不需要exports @MarkBell 三年后,但是.. 今天用 Mocha 进行了浏览器测试,使用 github.com/nathanboktae/mocha-phantomjs。 PhantomJS 是一个完整的无头浏览器,因此无需注入任何导出语句。【参考方案2】:

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

module.exports

如你所知;)

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

function testFunction()  /* code */ 

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

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

【讨论】:

【参考方案3】:

感谢此处的其他答案,我的工作正常。

但没有提到的一件事——也许是因为它是 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);
        )
    )
)

【讨论】:

+1 和@dinchev。我现在正在使用它,还没有找到更好的方法,但是,这会导致覆盖率较低,因为 functions.js 中的那些行没有被任何测试执行,只有 mocha 规范

以上是关于如何使用 Mocha 测试“正常”(非节点特定)JavaScript 函数?的主要内容,如果未能解决你的问题,请参考以下文章

节点 - 使用 mocha 测试时更改输出颜色

如何为 mocha 指定测试目录?

如何在 vs 代码中使用 mocha 生成覆盖率报告?

在mocha测试中调用异步函数如何避免超时错误:超过2000ms的超时

使用 Mocha 和 Chai-as-Promised 测试被拒绝的 Promise 的特定属性

markdown 节点单元测试备忘单:Mocha,Chai和Sinon