2012-07-03 152 views
0

在以下假設導航模塊的實現中,模塊對象返回屬性,如isOverBindedisNavTurnedOff,它們基本上會返回其他方法的結果值。模塊模式單元測試

然後在測試用例中使用此方法來檢查屬性調用是否導致其預期後果。

是否應該保留這些方法,或者有問題的原始方法是否返回相應的值以及測試用例中使用的相同方法?

目前的代碼是:

var navModule = (function(element) { 

     var nav = {}; 

     var navHTMLobjs = { 

      navList : element, 

      listItems : element.find('li'), 

      listLinks : element.find('a') 

     }; 

     nav.bindOver = function() { 

      navHTMLobjs.navList.on('mouseover mouseout', 'li a', function(e) { 

       if (e.type == 'mouseover') { 

        $(this).addClass('over'); 

       } 

       if (e.type == 'mouseout') { 

        $(this).removeClass('over'); 
       } 

      }); 

     }; 

     nav.isOverBinded = function(){ 

      return navHTMLobjs.navList.data('events').hasOwnProperty('mouseover') 

       && navHTMLobjs.navList.data('events').hasOwnProperty('mouseout'); 

     }; 

     nav.turnOff = function() { 

      navHTMLobjs.navList.off('mouseover mouseout'); 

     }; 

     nav.isNavTurnedOff = function() { 

      return !navHTMLobjs.navList.data.hasOwnProperty('events'); 

     }; 

     nav.init = function() { 

      this.bindOver(); 

     }; 

     return nav; 

    }); 

    var myNav = new navModule($('#nav')); 

    /// Test cases: 

    module('Navigation module'); 

    test('Binding total', function() { 

     myNav.init(); 

     equal(myNav.isOverBinded(), true, "Does the init function attach all events?"); 

    }); 

    test('Unbinding total', function() { 

     myNav.turnOff(); 

     equal(myNav.isNavTurnedOff(), true, "Does the cancel function correctly unbind events?"); 

    }); 

比如我應該改變nav.bingOver是:

nav.bindOver = function() { 

      navHTMLobjs.navList.on('mouseover mouseout', 'li a', function(e) { 

       if (e.type == 'mouseover') { 

        $(this).addClass('over'); 

       } 

       if (e.type == 'mouseout') { 

        $(this).removeClass('over'); 
       } 

      }); 

      return navHTMLobjs.navList.data('events').hasOwnProperty('mouseover') 

       && navHTMLobjs.navList.data('events').hasOwnProperty('mouseout'); 

     }; 

...然後用同樣的方法在測試用例像下面?

test('Binding total', function() { 

     myNav.init(); 

     equal(myNav.bindOver(), true, "Does the init function attach all events?"); 

    }); 

兩者有什麼不同?

非常感謝

+1

它在很大程度上不取決於您打算如何使用功能?它對函數返回適當的值很有好處。它可以讓你在測試時不必管理狀態。同時,如果您必須獨立檢查事件是否已訂閱,則應用程序的某些其他部分取決於該信息,因此您希望將其作爲函數公開。我不是在寫這個答案,因爲我覺得沒有正確的答案。也許有更多經驗的人可能會有一個。 –

+0

感謝Amith在這個問題上的接觸。我想我腦海中的問題來自於返回值的偶爾複雜性,即當模塊運行時額外的代碼運行,所以儘管我知道有函數總是返回一些是好的,但我不願意將這樣長的行作爲返回值每次部分運行,因此他們作爲一個單獨的方法分離。我想另一個問題是,雖然函數應該返回一個允許其可測試性的事物,應該在多大程度上遵循 – XGreen

+1

是否需要閱讀這樣長的行?還是計算回報值需要時間?如果它是第一個,那麼你可以簡單地選擇'return isOverBinded()',其中'isOverBinded'是一個本地私有函數,而不是公共函數。就我個人而言,當我有些複雜或長期的謂詞時,我會這麼做。用自解釋名稱隱藏實際計算背後的函數。 –

回答

2

假設應用程序的其他部分並不需要獨立驗證是否事件已經訂閱的bindOver()不應返回任何值。另外,isOverBinded()不屬於導航模塊。它的存在純粹是爲了幫助實施測試。在這種情況下,該功能應該在測試套件中。

var navModule = (function(element) { 

    var nav = {}; 

    var navHTMLobjs = { 
     navList : element, 
     listItems : element.find('li'), 
     listLinks : element.find('a') 
    }; 

    nav.bindOver = function() { 
     navHTMLobjs.navList.on('mouseover mouseout', 'li a', function(e) { 
      if (e.type == 'mouseover') { 
       $(this).addClass('over'); 
      } 

      if (e.type == 'mouseout') { 
       $(this).removeClass('over'); 
      } 
     }); 
    }; 

    nav.turnOff = function() { 
     navHTMLobjs.navList.off('mouseover mouseout'); 
    }; 

    nav.init = function() { 
     this.bindOver(); 
    }; 

    return nav; 
}); 

//var myNav = new navModule($('#nav')); 

/// Test cases: 

module('Navigation module'); 

// you might already have such a in memory object 
$root = $('<ul></ul>').append('<li><a href="#"></a></li><li><a href="#"></a></li>'); 
var myNav = new navModule($root); 

test('Binding total', function() { 

    myNav.init(); 

    equal(isOverBinded(), true, "Does the init function attach all events?"); 

}); 

test('Unbinding total', function() { 

    myNav.turnOff(); 

    equal(isNavTurnedOff(), true, "Does the cancel function correctly unbind events?"); 

}); 

var isNavTurnedOff = function() { 
    return $root.data('events').hasOwnProperty('mouseover') && $root.data('events').hasOwnProperty('mouseout'); 
} 

var isOverBinded = function() { 
    return $root.data.hasOwnProperty('events') === false; 
} 

在這一天,我覺得結束,是否不應該函數返回一個值應取決於功能的使用,而不是製造測試更容易。

+0

好的一個Amith。我從這裏得到了更多啓示:)謝謝 – XGreen