Тестирование частных членов в Javascript с использованием Sinon

Я начинаю писать некоторые тесты javascript и пытаюсь выяснить, какой лучший подход для проверки частных членов конструктора модуля. Например, в примере ниже я использую шаблон раскрывающего модуля, чтобы открыть публичный api для моего модуля. Я хочу проверить, что privateVar правильно установлен во время обратного вызова запроса $.getJSON ajax.

Второй тест it('should update privateVar', ...), не работает, потому что myModule.privateVar (намеренно) не находится в общедоступном api для модуля.

Итак, мой вопрос: Каков наилучший способ протестировать такое поведение, не делая частную часть publicvar публичного 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();
                });
            });


        });

    }
);

Ответы

Ответ 1

Что вы здесь говорите, к сожалению, требуется тест интеграции, вы хотите проверить, что переменная задана в результате внешней операции. Вы должны верить, что внешний метод просто работает для вашего теста, пропуская его в вашем как вы это делали с синоном, это позаботится о внешнем вызове.

Что нужно сделать, так это управлять условиями теста (скажем, без аутентификации и аутентификации), а затем проверить, каков результат функции в этом случае. Как правило, я обычно не тестирую закрытых членов, но я проверяю желаемое поведение в результате известных хороших и плохих значений.

Я также недавно прочитал это, в котором обсуждаются частные вары.

Ответ 2

Единственный способ получить доступ к вашим приватным переменным таким образом - это добавить публичный получатель, который вы можете позже вызвать в своем тесте, чтобы проверить состояние:

В вашем классе:

getPrivateVar: function() {return privateVar; }

Затем добавьте в оператор return:

return {getPrivateVar: getPrivateVar,};

Ответ 3

Собственно зачем тестировать приватную переменную? Это невозможно/сложно. И какова цель этой переменной? Если он будет передан в качестве аргумента для функции, вы можете проверить функцию, шпионя, если функция вызывается с определенным значением, которое было назначено частной переменной.

Ответ 4

Вы можете использовать rewire

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

чтобы вернуться обратно, просто вызовите revertBack(); Для более подробной информации смотрите https://www.npmjs.com/package/rewire