Тестирование частных членов в 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