Тестирование в закрытии JavaScript - PullRequest
15 голосов
/ 08 июля 2011

Можно ли выполнить модульное тестирование функций javascript, которые существуют в замыкании, например, с учетом следующего:

(function() {
  var a = function() {
    //do something
  }
  window.b =  function() {
    // do something else
  }
})();

Возможно ли выполнить модульное тестирование функции a без ее раскрытия?Если нет, есть ли хороший способ выставить, но только в тестовом режиме?

Ответы [ 3 ]

8 голосов
/ 08 июля 2011

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

Только мои .02 $

3 голосов
/ 08 июля 2011

Самый большой вопрос здесь - почему вы хотите скрыть это?Тот факт, что у вас есть эта функция, которую вы хотите протестировать, является показателем того, что она несет свою собственную ответственность, которую следует протестировать.Вытаскивание и тестирование приобретают гораздо большую ценность, если сравнивать с минимальным риском разоблачения.Если вы действительно хотите скрыть это, то я бы предложил нечто похожее на ответ Манукса, где вы создаете объект, который делает то, что делает, но не выставляет непосредственно.Затем вы можете проверить поведение a, протестировав этот объект.

1 голос
/ 02 июля 2015

Возвращаясь к вопросу через 4 года, теперь у меня есть лучшее решение.

Создание тестируемой версии вашего кода в качестве шага сборки.

Скажем, я использую Gulp для минимизации своегоJavaScript, и мой код выглядит так:

var a = function() {}
window.b = function() {}

Не отсутствие замыкания.Теперь я настроил задачу gulp и заставил ее смотреть мой код, например:

gulp.task('js', function () {
  return gulp.src([dirs.js.src, '*.js'].join('/'))
    .pipe(wrap('(function() {\n<%= contents %>\n})();'))
    .pipe(jshint())
    .pipe(jshint.reporter('default'))
    .pipe(gulp.dest(dirs.js.dest));
});

. Это обернет мой код в IIFE, создавая следующий вывод:

(function() {
var a = function() {}
window.b = function() {}
)();

Генерацияtestable version

Теперь я добавляю еще одну задачу Gulp, например:

gulp.task('testJs', function () {
  return gulp.src([dirs.test.src, '*.js'].join('/'))
    .pipe(wrap(
      [
        '(function() {',
          '<%= contents %>',
          '// Smuggle locals out of closure for testing',
          'window.a = a;',
        '})();'
      ].join('\n')
    ))
    .pipe(concat(package.name + '.testable.js'))
    .pipe(gulp.dest(dirs.test.dest));
});

. В моем тестовом каталоге будет сгенерирован следующий небезопасный, но тестируемый код:

(function() {
var a = function() {}
window.b = function() {}
// Smuggle locals out of closure for testing
window.a = a;
)();

Добавьте задачу наблюдения ...

gulp.task('watch', function() {
  gulp.watch([dirs.js.src, '**', '*.js'].join('/'), ['js', 'testJs']);
});

... и все готово.

См. Здесь

См. Пример для примера:

https://github.com/forwardadvance/ng-tweets

...