Как я могу заглушить / смокировать функцию в глобальном пространстве имен javascript - PullRequest
15 голосов
/ 20 декабря 2010

Я пытаюсь заблокировать / смоделировать / переопределить вызов функции во время тестирования, который записывает журнал в БД.

function logit(msg) {
  writeMessageToDb(msg);
}

function tryingToTestThisFunction(){
  var error = processSomething();
  if (error) {
    logit(error);
  }
}

Я бы хотел, чтобы logit() просто печатал на консоль во время тестирования... и выполнение блока "isTesting()" if / else внутри функции logit() не вариант.

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

Ответы [ 6 ]

7 голосов
/ 28 июля 2011

Я использую Jasmine и Sinon.js (используя Coffeescript), вот как я заглушаю метод verify () , чтобы, например, просто вернуть true.

beforeEach ->
  @confirmStub = sinon.stub(window, 'confirm')
  @confirmStub.returns(true)

afterEach ->
  @confirmStub.restore()
3 голосов
/ 20 декабря 2010

В javascript распространено последнее определение.

, поэтому просто переопределите метод logit после первого определения.

function logit(msg) {
  console.log(msg);
}

пример: http://www.jsfiddle.net/gaby/UeeQZ/

1 голос
/ 31 октября 2013

Я работал над точно такой же проблемой. Разработчики дали мне приложение HTML5 для тестирования, поэтому, конечно, я не могу изменить их код для тестирования. Я решил использовать qunit и sinon вместе с sinon-qunit.

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

Функция, которую я должен вызвать - caller(), и я ничего не могу сделать с stubme(), потому что она в коде разработчика. Тем не менее, я могу добавить sinonstub() в мой тестовый код. Но как заставить его работать с sinon? Документация по sinon действительно смутила меня некоторое время, но ниже приведено простое решение. Объект 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>
1 голос
/ 16 декабря 2011

просто переопределите функцию logit, ее можно вызвать в любое время позже, чем определено 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))
    }
  }
}());
1 голос
/ 20 декабря 2010

Вы можете просто переопределить метод объекта окна?В консоли Chrome это работает

function test() {console.log('test')};
window.test();
0 голосов
/ 20 октября 2015

Поскольку в 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.
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...