Как я могу заглушить/издеваться над функцией в глобальном пространстве имен javascript
Я пытаюсь заглушить/издеваться/переопределить вызов функции во время тестирования, который записывает журнал в БД.
function logit(msg) {
writeMessageToDb(msg);
}
function tryingToTestThisFunction(){
var error = processSomething();
if (error) {
logit(error);
}
}
Я бы хотел, чтобы logit()
просто печатал на консоли во время тестирования... и делал "isTesting()
", если/else-блок внутри функции logit()
не является опцией.
Возможно ли это без включения какой-либо дополнительной фальшивой структуры. В настоящее время я использую JsTestDriver
для модульного тестирования и не имел возможности оценить какие-либо насмешливые рамки. Идеальным решением на данный момент было бы обращение к этому без использования другой структуры.
Ответы
Ответ 1
Я использую Jasmine и Sinon.js(используя Coffeescript), здесь, как я оканчиваю метод confirm(), например, просто return true.
beforeEach ->
@confirmStub = sinon.stub(window, 'confirm')
@confirmStub.returns(true)
afterEach ->
@confirmStub.restore()
Ответ 2
В javascript последнее определение является распространенным.
так что просто переопределите метод logit после первого определения.
function logit(msg) {
console.log(msg);
}
example: http://www.jsfiddle.net/gaby/UeeQZ/
Ответ 3
Можно ли просто переопределить метод на объекте окна? В консоли Chrome это работает
function test() {console.log('test')};
window.test();
Ответ 4
просто переопределить функцию logit, это можно вызвать в любое время позже, чем определяется логит.
(function(){
//keep handle to original logit method.
var ol = logit;
//shorter lookup path for slice
var s = Array.prototype.slice;
//logit override
logit = function() {
//if in testing
if (typeof IsTesting == "function" && !!IsTesting()) {
//log the arguments
console.log.apply(console, s.call(arguments));
} else {
//otherwise, call the original function.
ol.apply(this, s.call(arguments))
}
}
}());
Ответ 5
Я работал над одной и той же проблемой. Разработчики дали мне приложение HTML5 для тестирования, поэтому, конечно, я не могу изменить свой код для тестирования. Я решил использовать qunit и sinon, наряду с синон-qunit.
Для тестирования модуля newb для JavaScript, подобного мне, я собирался сходить с документацией по синону и различными примерами в Интернете, поскольку большинство из них кажется для подразумеваемой среды, о которой не упоминалось. Код ниже - это полная страница, поэтому я надеюсь, что ничего не останется для путаницы.
Функция, которую я должен вызвать, это caller()
, и я ничего не могу сделать о stubme()
, потому что это в коде разработчика. Тем не менее, я могу добавить sinonstub()
в свой тестовый код. Но как заставить его работать с синоном? Документация по синону действительно немного смутила меня, но ниже это простое решение. Объект stub4stubme можно использовать для управления действием заглушки, а также получить информацию о том, что происходит с вызовами заглушки.
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
<link rel="stylesheet" href="qunit-1.12.0.css" type="text/css" media="screen" />
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<script src="sinon-1.7.3.js"></script>
<script src="qunit-1.12.0.js"></script>
<script src="sinon-qunit-0.8.0.js"></script>
<script>
// Dev code in another file
function stubme() {
return "stubme";
}
function caller() {
return "caller " + stubme();
}
// End of dev code
var sinonstub = function () {
return "u haz bin stubbed";
};
test("Stubbing global environments", function () {
equal(caller(), "caller stubme");
var stub4stubme = this.stub(window, "stubme", sinonstub);
equal(caller(), "caller u haz bin stubbed");
ok(stubme.called);
});
</script>
</body>
</html>
Ответ 6
Потому что в Javascript связано не только время исполнения, но и последнее слово, получившее ссылку, просто переопределите метод с поведением, которое вы хотите в своем тесте:
function yourTest(){
oldImpl = logit; // better to use a setup.
logit = function(msg){ Console.log.apply(console, s.call(arguments));};
// do you assertions: assert.... yada.
logit = oldImpl; // Do this to keep your test isolated from the others you'll be executing in this test run. Better to use a tear down.
}