首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用Mocha和Node.js对私有函数进行单元测试

使用Mocha和Node.js对私有函数进行单元测试
EN

Stack Overflow用户
提问于 2014-02-28 22:17:13
回答 9查看 67K关注 0票数 147

我使用Mocha对为Node.js编写的应用程序进行单元测试。

我想知道是否有可能对模块中未导出的函数进行单元测试。

示例:

我在foobar.js中定义了很多这样的函数

代码语言:javascript
复制
function private_foobar1(){
    ...
}

function private_foobar2(){
    ...
}

以及一些导出为public的函数:

代码语言:javascript
复制
exports.public_foobar3 = function(){
    ...
}

测试用例的结构如下:

代码语言:javascript
复制
describe("private_foobar1", function() {
    it("should do stuff", function(done) {
        var stuff = foobar.private_foobar1(filter);
        should(stuff).be.ok;
        should(stuff).....

显然,这是不起作用的,因为private_foobar1没有被导出。

对私有方法进行单元测试的正确方法是什么?Mocha有没有一些内置的方法来做到这一点?

EN

回答 9

Stack Overflow用户

回答已采纳

发布于 2014-02-28 23:47:08

如果该函数不是由模块导出的,则无法由模块外部的测试代码调用该函数。这是由于JavaScript的工作方式,而Mocha本身无法绕过这一点。

在少数情况下,我确定测试私有函数是正确的,我设置了一些环境变量,我的模块会检查这些变量,以确定它是否在测试设置中运行。如果它在测试设置中运行,那么它将导出额外的函数,然后我可以在测试期间调用这些函数。

“环境”这个词在这里用得不够严谨。这可能意味着检查process.env或其他可以与“你现在正在被测试”模块通信的东西。我不得不这样做的实例是在RequireJS环境中,为此我使用了module.config

票数 71
EN

Stack Overflow用户

发布于 2015-07-17 03:21:16

查看rewire模块。它允许您获取(和操作)模块中的私有变量和函数。

因此,在您的示例中,用法类似于:

代码语言:javascript
复制
var rewire = require('rewire'),
    foobar = rewire('./foobar'); // Bring your module in with rewire

describe("private_foobar1", function() {

    // Use the special '__get__' accessor to get your private function.
    var private_foobar1 = foobar.__get__('private_foobar1');

    it("should do stuff", function(done) {
        var stuff = private_foobar1(filter);
        should(stuff).be.ok;
        should(stuff).....
票数 195
EN

Stack Overflow用户

发布于 2015-07-03 16:13:29

谷歌工程师菲利普·沃尔顿在他的博客上解释了Here is a really good workflow to test your private methods

原则

正常编写您的代码,并将您的私有方法绑定到单独代码块中的对象,并用注释标记它( example)

  • Surround
  • _

然后使用一个构建任务或您自己的构建系统(例如grunt strip code)来为生产构建剥离这个块。

您的测试构建可以访问您的私有API,而您的生产构建则不能。

代码段

按如下方式编写代码:

代码语言:javascript
复制
var myModule = (function() {

  function foo() {
    // Private function `foo` inside closure
    return "foo"
  }

  var api = {
    bar: function() {
      // Public function `bar` returned from closure
      return "bar"
    }
  }

  /* test-code */
  api._foo = foo
  /* end-test-code */

  return api
}())

您的Grunt任务如下所示:

代码语言:javascript
复制
grunt.registerTask("test", [
  "concat",
  "jshint",
  "jasmine"
])
grunt.registerTask("deploy", [
  "concat",
  "strip-code",
  "jshint",
  "uglify"
])

更深层次

In a later article,它解释了“测试私有方法”的“原因”

票数 26
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22097603

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档