如何在javascript中测试var中的函数

如何在javascript中测试var中的函数,javascript,testing,reactjs,Javascript,Testing,Reactjs,下面给出一段代码,它是从 但它抱怨错误 FAIL src/lib/rl.test.js ✕ sampleWeighted (1ms) ● sampleWeighted TypeError: _rl.RL.sampleWeighted is not a function at Object.<anonymous> (src/lib/rl.test.js:7:46) at process._tickCallback (internal/p

下面给出一段代码,它是从

但它抱怨错误

 FAIL  src/lib/rl.test.js
  ✕ sampleWeighted (1ms)

  ● sampleWeighted

    TypeError: _rl.RL.sampleWeighted is not a function

      at Object.<anonymous> (src/lib/rl.test.js:7:46)
      at process._tickCallback (internal/process/next_tick.js:103:7)
src/lib/rl.test.js失败
✕ 采样加权(1ms)
● 样本加权
TypeError:_rl.rl.sampleWeighted不是函数

反对。设置测试框架。那么,测试上述功能的正确方法是什么呢?如果您碰巧理解了
sampleWeighted
的功能,也请随意评论。

sampleWeighted是您的
iLife
的结尾(即时函数调用语法)

通过这种方式,您可以像Java中的
private-public
一样保持方法的私有性,注意,您已经传递了全局值,即RL,您可以将其视为名称空间,如果您想调用sampleWeighted,您需要将sampleWeighted附加到
RL

...
RL.sampleWeighted = function() {}
...

在闭包中编写代码,使我们的测试代码能够访问我们关心的私有函数,但当我们部署到生产环境中时,请删除该代码。 在这里,您可以准确地编写代码,使其在发布时显示为您希望的样子,然后添加您需要的任何桥接代码,以公开您想要测试的部分

如果您使用的是构建系统,您完全可以做到这一点。

var RL = {};
(function(global) {
    var sampleWeighted = function(p) {
        var r = Math.random();
        var c = 0.0;            // cumulative prob
        for(var i=0, n=p.length; i<n; i++) {
            c += p[i];
            if (c >= r) { return i; }
        }
        // assert(false) may happen if sum(p) < 1;
        assert(false, 'wtf');
    };

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

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

    return api    

})(RL);

export default RL;
然后在GrunFile中启用它:

grunt.loadNpmTasks('grunt-strip-code');


grunt.initConfig({
  strip_code: {
    options: {
      start_comment: "test-code",
      end_comment: "end-test-code",
    },
    your_target: {
      // a list of files you want to strip code from
      src: "dist/*.js"
    }
  }
})


grunt.registerTask("test", [
  "concat",
  "jshint",
  "jasmine"
])
grunt.registerTask("deploy", [
  "concat",
  "strip-code",
  "jshint",
  "uglify"
])

重新引用-

在您的IIFE中,您没有将
sampleWeighted
附加到传入的对象(全局)。所以,在你的生活中,一定要做如下的事情:

global.sampleWeighted = sampleWeighted;
此外,在测试文件中,您需要使用以下方式访问该函数:

RL.sampleWeighted

我希望这能有所帮助。

不要使用
var-sampleWeighted
,而是尝试
global.sampleWeighted
你是说代码的编写方式不稳定吗?如果可能的话,我试着遵循原作者的惯例
sampleWeighted
IIFE
中的一个私有函数。它内部的代码可以使用它,但外部代码无法使用。我怀疑您忽略的行中可能有一些代码很重要,特别是当sampleWeighted附加到RL对象时。它的IIFE(立即调用的函数执行)和它的not closurescope@Rajesh,你能确认它在
var sampleWeighted
中的写入方式是不稳定的吗?此外,这是否意味着如果需要测试,我们根本不应该编写这样的代码?如果我想在
(函数(全局){……}中的另一部分代码中调用
sampleWeighted
,该怎么办
,应该如何调用它?
全局。sampleWeight
看起来很冗长,是吗?@Rajesh的生命不是通过clousure完成的?当一个函数在另一个函数中执行并使用封闭函数中的变量时,它是一个clousure@Sean没有必要。如果你看到OP的代码,它是一个没有包装在函数中的生命。所以我假设它是用于防止污染全局范围。这不起作用,你必须将你的api附加到全局对象上。你不能只返回api。grunt-strip-code看起来有点粗糙,这样做是一种最佳做法吗?它起作用了。我有这样的印象,即这种生活方式正在随着ES6的模块系统逐步淘汰(例如,这是对的吗?在某种程度上,对于某些用途……但如果您希望在脚本解析后立即执行函数,也可以使用IIFE,我不确定ES6模块的设计目的是什么。
grunt.loadNpmTasks('grunt-strip-code');


grunt.initConfig({
  strip_code: {
    options: {
      start_comment: "test-code",
      end_comment: "end-test-code",
    },
    your_target: {
      // a list of files you want to strip code from
      src: "dist/*.js"
    }
  }
})


grunt.registerTask("test", [
  "concat",
  "jshint",
  "jasmine"
])
grunt.registerTask("deploy", [
  "concat",
  "strip-code",
  "jshint",
  "uglify"
])
global.sampleWeighted = sampleWeighted;
RL.sampleWeighted