簡體   English   中英

如何在jquery插件中對私有方法進行單元測試?

[英]how to unit-test private methods in jquery plugins?

也許這是一個新手JQuery問題但是:

  • 正確的jquery插件寫在一個閉包內
  • 因此,只能從外部訪問定義插件接口的方法
  • 有時(或多次)可能需要幫助方法,因為它們作為插件接口的一部分公開是沒有意義的(例如因為它們改變了內部狀態)。
  • 那些如何進行單元測試?

例如,看看blockUI插件,方法如何安裝,刪除,重置獲得單元測試?

要在Java中繪制並行,我會:

  1. 創建一個僅包含公共方法的BlockUI接口(根據定義)
  2. 創建一個實現上述接口的BlockUIImpl類。 此類將包含install(),remove(),reset()方法,這些方法可以是公共的,或(包)受保護的

所以,我會對Impl進行單元測試,但客戶端程序員會通過BlockUI接口與插件進行交互。

這同樣適用於任何其他語言和測試私有:要測試私有方法,您應該通過公共接口來練習它們。 換句話說,通過調用您的公共方法,私有方法在該過程中進行測試,因為公共方法依賴於私有方法。

通常,私有方法不會與公共接口分開測試 - 整個問題是它們是實現細節,測試通常不應該對實現的細節有太多了解。

在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);

但不要忘記你不應該真的測試私人。 ;)

我提出了同樣的問題,在瀏覽並找到不適用的答案后,我最終解決了類似的問題。

問題:“我有一個小部件,它有一個我想要測試的行為以確保它按預期工作,一些方法在內部調用,因為它們必須解決內部行為,將它們暴露為公共沒有意義,因為它們不會被調用從外面來看,測試公共方法意味着你不會測試小部件的內部,所以最后我該怎么辦?“

解決方案:“Creata是一個測試小部件,它公開了你有興趣測試的方法,並在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將處理測試,這解決了我的問題,希望這適用於有麻煩接觸這類測試的其他人。

批評? 歡迎發表評論,如果我做傻事我想改進這個!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM