Тестирование приватных функций в javascript - PullRequest
16 голосов
/ 04 апреля 2009

Я использую шаблон модуля в Javascript, чтобы отделить мой открытый интерфейс от частной реализации. Чтобы упростить то, что я делаю, мой код генерирует диаграмму. Диаграмма состоит из нескольких частей (оси, метки, сюжет, легенда и т. Д.). Мой код выглядит так:

var Graph = function() {
  var private_data;
  function draw_legend() { ... }
  function draw_plot() { ... }
  function helper_func() { ... }
  ...

  return {
    add_data: function(data) {
      private_data = data;
    },
    draw: function() {
      draw_legend()
      draw_plot()
    }
  }
}

Некоторые люди рекомендуют только тестировать открытый интерфейс ваших классов, что имеет смысл, но я бы очень хотел пройти несколько тестов, чтобы протестировать каждый из компонентов в отдельности. Если я испорчу свою функцию draw_legend (), я бы хотел, чтобы этот тест провалился, а не тест для публичной функции draw (). Я здесь не на том пути?

Я мог бы разделить каждый из компонентов на разные классы, например, сделать класс Legend. Но кажется глупым создавать класс для того, что иногда составляет всего 5-10 строк кода, и это было бы уродливее, потому что мне нужно было бы передать кучу приватных состояний. И я не смог бы проверить свои вспомогательные функции. Должен ли я сделать это в любом случае? Должен ли я смириться с этим и протестировать только публичную ничью ()? Или есть какое-то другое решение?

Ответы [ 6 ]

9 голосов
/ 05 апреля 2009

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

На самом деле Javascript - это объектно-ориентированный язык. Это просто не типизированный.

5 голосов
/ 29 января 2013

Мое решение - просто взломать. Пример:

В начале html теста Qunit я объявил:

var TEST_AVAILABLE = true;

В тестируемом классе у меня есть такой фрагмент:

if(TEST_AVAILABLE){
   this.test={
      hasDraft:hasDraft,
      isInterpIdIn:isInterpIdIn,
      // other private methods
   };
}

В QUnit вы можете проверить

test( "hello booth", function() {
  var b = new Booth();
  ok(b);
  ok(b.test);
  ok(!b.test.hasDraft());
});
3 голосов
/ 08 октября 2012

У меня похожая проблема. Решение, которое я придумал, не то, что мне нравится, но оно выполняет свою работу, и лучшего решения я не могу найти.

function Graph()
{
    this.Test = function _Test(expressionStr) { return eval(expressionStr); }

    var private_data;
    function draw_legend() { ... }
    function draw_plot() { ... }
    function helper_func() { ... }
    ...
}

Для проверки:

var g = new Graph();
g.Test("helper_func()") == something;
g.Test("private_data") == something2
1 голос
/ 24 августа 2012

Существует простой способ на самом деле. Вы можете использовать ajax для загрузки скрипта и внедрения функции, которая предоставляет приватные функции. У меня есть пример здесь , который использует qUnit и jQuery. Но я уверен, что то же самое можно легко сделать, используя чистый Javascript.

0 голосов
/ 06 декабря 2016

Существует только один правильный вариант: Различные сборки для тестирования и производства

1) отметка о разработке только деталей

/* test-code */
api._foo = foo
/* end-test-code */

2) раздеть их позже ...;)

grunt.registerTask("deploy", 
  [
    "concat",
    "strip-code",
    ...

@ Филвальтон написал прекрасные статьи:

0 голосов
/ 04 апреля 2009

В объектно-ориентированном языке вы обычно тестируете защищенные методы модульно, если тестовый класс наследует от класса, который он тестирует.

Конечно, Javascript на самом деле не является объектно-ориентированным языком, и этот шаблон не допускает наследования.

Я думаю, что вам нужно либо опубликовать свои методы, либо отказаться от модульного тестирования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...