2

这似乎是不可能的(而且可能是),但我正在尝试更多的 TDD,而且我一直在用闭包碰壁。说我有以下内容:

function createSomething(init) {
    function privateMethod(param) {
        return init[param];  //assuming this is more complicated, how can you test it?
    }

    function getData() {
        return init.data;
    }

    function getValue(name) {
        if (name === "privateNode" || typeof name !== "string") {
            return "permissionDenied";
        }
        return privateMethod(name);
    }

    return {
        getData : getData,
        getValue: getValue
    };
}

抛开这段代码可能不是我观点的最佳说明,并假设“privateMethod”比上面的要复杂得多,有没有办法对“privateMethod”之类的方法运行单元测试或者是你能做的最好的是测试createSomething创建的对象吗?我问是因为我的应用程序的大部分都隐藏在闭包中。我在这方面非常不了解,但在我看来,这是 javascript 和 tdd 的弱点。上面没有 tdd 的代码的小提琴在这里:http: //jsfiddle.net/QXEKd/

4

2 回答 2

3

您可以通过向构造函数添加额外的参数或硬编码提前返回,很容易地将函数(或函数、变量等的对象)从闭包中“走私”出来。smuggled 函数应该仍然有从它被偷运的地方的闭包,除非你正在做类似 evil 的事情。eval

值得注意的是,如果您仅出于测试目的而将此类功能取出,则最好在将其发布到您的网站之前注释掉或以其他方式删除代码以访问这些代码,这样就不会被滥用。另外,请注意this,如果您正在使用它,它将根据调用函数的方式而改变。

例如_

function createSomething(init, aaa) {
    function privateMethod(param) {
        return init[param];  //assuming this is more complicated, how can you test it?
    }

    function getData() {
        return init.data;
    }

    function getValue(name) {
        if (name === "privateNode" || typeof name !== "string") {
            return "permissionDenied";
        }
        return privateMethod(name);
    }
    // ----------------------------------
    if(aaa) return privateMethod;
    // ----------------------------------
    return {
        getData : getData,
        getValue: getValue
    };
}

var something = createSomething({
    privateNode : "allmysecrets",
    id : "1234",
    data : {
        stuff : "32t97gfhw3hg4"
    }
}, 1); // passing extra arg to get method

console.log(
    something('id'),
    something('privateNode')
) // 1234 allmysecrets
于 2013-01-04T15:47:56.607 回答
0

另一种可能性是导出一个添加测试用例的函数。它不会导出任何超出范围(私人)的东西。

我主要使用 Mocha 进行测试,所以我从添加测试的那个函数中调用“describe()”和“it()”。例如,假设我创建了一个名为“whatever”的库。我可以创建一个函数“test”(或 _test、_addTests、...):

var whatever = (function() {
  var insideClosure = "Ha ha!";
  return {

    // obviously you would have other functions too
    test: function() {
      describe('something', function() {
        it('should work', function() {
          assert.equal(insideClosure, "Ha ha!");
        });
      });
    }
  };
})();

然后我的 ./test/tests.js 会有:

whatever.test();

一个明显的坏点是您无法分离纯代码和测试(除非可能使用某种部署工作流程)。

于 2015-07-02T03:53:04.747 回答