16

我开始编写一些 javascript 测试并试图找出检查模块构造函数的私有成员的最佳方法。例如,在下面的示例中,我使用显示模块模式将公共 api 公开给我的模块。我想测试在ajax 请求privateVar回调期间是否正确设置。$.getJSON

第二个测试it('should update privateVar', ...),不起作用,因为myModule.privateVar(故意)不在模块的公共 api 中。

所以,我的问题是,测试这种行为的最佳方法是什么,而不必使 privateVar 成为公共 api 的一部分?有没有更好的方法来考虑这个代码进行测试,或者可能有一种方法可以使用像 SinonJs 这样的东西来监视私人成员?

define('myModule',
    ['jquery'],
    function ($) {
        var
            myVar = "something",
            privateVar = "something else",

            doSomething = function() {
                return $.getJSON('http://myapi.com/do-something', { requestData : "some data" }, function(response){
                    myVar = response.data.value1;
                    privateVar = response.data.value2;
                });
            };

        return {
            doSomething : doSomething,
            myVar : myVar
        };
    }
);

define('test/test.myModule',
    ['myModule', 'chai', 'sinon', 'mocha'],
    function (myModule, chai, sinon) {

        describe("myModule", function() {
            var expect = chai.expect;

            describe('doSomething', function() {

                var value1 = 'value1 value',
                    value2 = 'value2 value';

                beforeEach(function() {
                    sinon.stub($, 'ajax').yieldsTo('success', {
                        data : { value1 : value1, value2 : value2 }
                    });
                });

                afterEach(function() {
                    $.ajax.restore();
                });

                it('should update myVar', function(done) {
                    myModule.doSomething();
                    expect(myModule.myVar).to.equal(value1);
                    done();
                });

                it('should update privateVar', function(done) {
                    myModule.doSomething();
                    expect(myModule.privateVar).to.equal(value2);
                    done();
                });
            });


        });

    }
);
4

4 回答 4

6

不幸的是,您在这里谈论的内容需要集成测试,您希望测试一个变量是否是由于外部操作而设置的,您应该相信外部方法只适用于您的测试,因为您在测试中将其存根已经完成了 sinon 这需要处理外部调用。

您需要做的是控制测试的条件(比如说未经身份验证和身份验证),然后测试该实例中函数的结果。作为一项规则,我通常根本不测试私有成员,但我会测试由已知的好值和坏值导致的期望行为。

我不久前也读过这篇文章,其中讨论了私有变量。

于 2013-03-01T09:22:37.063 回答
3

以这种方式访问​​私有变量的唯一方法是添加一个公共 getter,您可以稍后在测试中调用它来验证状态:

在你的课堂上:

getPrivateVar : function(){ return privateVar; }

然后添加到return语句:

返回 { getPrivateVar : getPrivateVar, };

于 2013-02-27T23:39:50.643 回答
0

实际上为什么要测试私有变量?这是不可能/困难的。该变量的目的是什么?如果它要作为参数传递给函数,当然可以通过监视函数是否使用分配给私有变量的特定值来调用函数来测试函数。

于 2016-04-20T10:28:53.210 回答
0

您可以使用重新布线

let revertBack = renderCtrl.__set__(privateMember,substituteMember);

要恢复,只需调用 revertBack(); 有关更多详细信息,请参阅https://www.npmjs.com/package/rewire

于 2019-08-08T16:23:24.233 回答