Как тестировать приватные методы в плагинах jquery? - PullRequest
13 голосов
/ 22 апреля 2011

Возможно, это немного новичок в вопросе JQuery, но:

  • правильные плагины jquery написаны внутри замыкания
  • , таким образом, только методы, определяющие интерфейс плагина, доступны извне
  • иногда (или много раз) могут понадобиться вспомогательные методы, которые не имеет смысла выставлять как часть интерфейса плагина (например, потому что они изменяют внутреннее состояние).
  • как они проходят модульное тестирование?

Например, глядя на плагин blockUI , как методы можно устанавливать, удалять,reset get get-test-only?

Чтобы провести параллель, в Java я бы:

  1. создал бы интерфейс BlockUI, содержащий только публичные методы (по определению)
  2. createкласс BlockUIImpl, реализующий вышеуказанный интерфейс.Этот класс будет содержать методы install (), remove (), reset (), которые могут быть общедоступными или (package) защищенными

Итак, я бы провел модульное тестирование Impl, но клиентские программисты взаимодействовали бы сплагин через интерфейс BlockUI.

Ответы [ 3 ]

13 голосов
/ 22 апреля 2011

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

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

2 голосов
/ 07 февраля 2012

Код, написанный внутри функции на JavaScript, или замыкание , как вы его вызвали, не обязательно изолированы от внешней стороны этой функции.

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

Этот простой пример с плагином jQuery и искусственным «пространством имен» может служить для подтверждения этого предположения:

// Initialise this only when running tests
my_public_test_namespace = function(){};

jQuery.fn.makeItBlue = function() {

    makeItBlue(this);

    function makeItBlue(object) {
        object.css('color','blue');
    }

    if(typeof my_public_test_namespace != "undefined") {
        my_public_test_namespace.testHarness = function() {
            return {
                _makeItBluePrivateFn: makeItBlue
            }
        };
    }
};

$("#myElement").makeItBlue(); // make something blue, initialise plugin

console.debug(my_public_test_namespace.testHarness()._makeItBluePrivateFn);

Но не забывайте, что вы не должны проверять рядовых.;)

0 голосов
/ 16 сентября 2016

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

Проблема: «У меня есть виджет, поведение которого я хочу проверить, чтобы убедиться, что он работает, как и ожидалось, некоторые методы вызываются изнутри, потому что они должны решать внутреннее поведение, выставлять их как публичные не имеет смысла, потому что они Если вы не будете вызывать извне, тестирование открытых методов означает, что вы не будете тестировать внутренние компоненты виджета, так что, наконец, я могу сделать? "

Решение: "Создайте тестовый виджет, который предоставляет интересующие вас методы тестирования, и используйте их в qunit, вот пример:"

// Namespaces to avoid having conflicts with other things defined similarly
var formeditortest = formeditortest || {};
// widget that inherits from the container I want to test
$.widget( "app.testcontainer", $.app.container,  {
    executeDrop: function(drop, helper) {
       var self = this;
       self._executeDrop(drop, helper);
    }
});
// Test cases
formeditortest.testDropSimple = function(assert) {
   var container = $("<div />");
   container.testcontainer();
   container.testcontainer("drop", 0, 3);
   assert.equal(true, $(innerDiv.children()[0]).hasClass("droparea"));
});

QUnit.test(name, function( assert ) {
   formeditortest.testDropSimple(assert);
   formeditortest.testDropBottom(assert);
});

Используя этот метод, унаследованный тестконтейнер может иметь подготовку, необходимую для тестирования элементов, и тогда qunit будет обрабатывать тест, это решит мою проблему, надеюсь, это сработает для кого-то еще, у которого есть проблемы с подходом к такого рода тестам. *

Критика? добро пожаловать комментировать, я хочу улучшить это, если я делаю что-то глупо !!!

...