QUnit несколько скриптов на одной странице, но между ними нет взаимодействия

Я очень новичок в модульном тестировании (это мой первый день работы с QUnit, и я никогда раньше не работал с какой-либо другой системой тестирования), и я немного не понимаю, как тестировать материал из нескольких файлов сценариев в одном QUnit. страницу, не позволяя сценариям взаимодействовать друг с другом. Я имею в виду, скажем, если у меня есть script1.js, и он вызывает hello(), а hello() определен в script2.js, как я могу запустить модульный тест на script1.js, чтобы убедиться, что он вызывает hello(), но имитировать вывод hello(), чтобы это был истинный модульный тест, а затем запустите hello() script2.js.

По сути, как мне скрыть глобальные переменные и функции одного скрипта из другого скрипта на одной странице QUnit?


person markasoftware    schedule 01.11.2014    source источник


Ответы (1)


Это полностью зависит от того, как организованы различные файлы сценариев, а также от системы в целом. Например, если вы использовали Angular, вы можете внедрять зависимости, когда включаете модуль в другой файл сценария. Существуют инструменты для имитации вещей и «шпионажа» за вызовами функций, такие как Sinon, но это все еще сильно зависит от того, как вы код организован.

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

// File A:
window.greeting = function() {
    var world = hello();
    return 'hello ' + world;
}

// File B:
window.hello = function() {
    // possibly lots of code to determine what to return...
    var value = 'foobar';
    return value;
}

Функция hello() могла бы так же легко возвращать любое другое значение в зависимости от состояния системы, пользовательского ввода и т. д. В нашем случае это не так, и мы хотим смоделировать код файла B, чтобы мы не нужно проверить, что он делает, просто возвращает строку. Мы могли бы (и должны) сделать это с помощью надлежащей библиотеки имитации/внедрения зависимостей. Однако просто чтобы дать вам представление о минимальной настройке, которую вы могли бы сделать, и чтобы увидеть общий подход, вот наш QUnit. тестовый файл:

var _hello;
QUnit.module('File A', {
  setup: function() {
    _hello = window.hello; // hold onto the old value
   // now we mock out hello()
    window.hello = function() {
      window.hello.called++;  // track calls to it
      return 'world'; // return our static value
    }
    window.hello.called = 0;
  },
  teardown: function() {
    // put the old one back
    window.hello = _hello || window.hello;
  }
});

QUnit.test('Ensure greeting is correct', function(assert) {
  var result = greeting();
  assert.equal(window.hello.called, 1, 'hello should be called only once');
  assert.equal(result, 'hello world', 'The greeting call should be "hello world"');
});

И если вы хотите увидеть, как он работает, вот вам jsfiddle. Как я уже сказал, это простой пример, показывающий, как вы могли это сделать, но вам следует обратить внимание на правильную организацию кода (например, модули AMD, require, Angular, Ember и тому подобное) и правильная насмешливая библиотека.

person Jordan Kasper    schedule 01.11.2014
comment
Итак, будет ли библиотека для насмешек (sinon.js, похоже, соответствует моим потребностям) переопределять функции, определенные в других файлах? Итак, если в файле 2 у меня есть функция hello(), но затем я использую sinon.js для имитации и создания фальшивой функции hello(), когда я вызываю hello() в файле 1, вызовет ли она фальшивое приветствие или вызовет приветствие что определено в файле 2? - person markasoftware; 02.11.2014
comment
Опять же, это все о том, как ваш код написан и организован. Синон может создать шпиона для функции hello() (но не макетировать его) с очень небольшими усилиями, но для создания истинного макета функции требуется возможность каким-то образом внедрить этот макет в ваш первый скрипт. Но, как я уже сказал, это полностью зависит от того, как написан ваш код. Если вы используете только глобальные функции, то у вас действительно не так много вариантов, кроме моего примера выше. - person Jordan Kasper; 02.11.2014