亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

AngularJs  unit-testing(單元測(cè)試)詳解

 更新時(shí)間:2016年09月02日 16:07:05   作者:Lcllao  
本文主要介紹AngularJs unit-testing(單元測(cè)試)的內(nèi)容,這里整理了單元測(cè)試的知識(shí),及示例代碼,有興趣的朋友可以參考下

 javascript是一門(mén)動(dòng)態(tài)類型語(yǔ)言,這給她帶來(lái)了很強(qiáng)的表現(xiàn)能力,但同時(shí)也使編譯器幾乎不能給開(kāi)發(fā)者提供任何幫助。因?yàn)檫@個(gè)原因,我們感受到編寫(xiě)任何javascript代碼都必須有一套強(qiáng)大完整的測(cè)試。angular擁有許多功能,讓我們更加容易地測(cè)試我們的應(yīng)用。我們應(yīng)該沒(méi)有借口不去寫(xiě)測(cè)試(這個(gè)嘛……)。

一、 It is all about NOT mixing concerns(全部都關(guān)于避免代碼關(guān)系變得復(fù)雜……)

  單元測(cè)試,正如名稱那樣,是關(guān)于測(cè)試單個(gè)“單元”的代碼。單元測(cè)試努力解答這些問(wèn)題:我對(duì)邏輯的考慮是否已經(jīng)正確?排序方法得出的結(jié)果是否正確?為了解答這些問(wèn)題,將這些問(wèn)題獨(dú)立出來(lái)顯得尤其重要。這是因?yàn)楫?dāng)我們?cè)跍y(cè)試排序方法的時(shí)候,我們不想關(guān)心其他相關(guān)的片段,例如DOM元素或者發(fā)起XHR請(qǐng)求獲取數(shù)據(jù)等。明顯地,通常比較難做到在典型的項(xiàng)目中單獨(dú)調(diào)用一個(gè)函數(shù)。導(dǎo)致這個(gè)問(wèn)題的原因是,開(kāi)發(fā)者通常把關(guān)系弄得很復(fù)雜,最終讓一個(gè)代碼片段看起來(lái)可以做所有事情。它通過(guò)XHR獲取數(shù)據(jù),對(duì)數(shù)據(jù)進(jìn)行排序,然后操縱DOM。與angular一起,我們可以更加容易地寫(xiě)出較好的代碼,所以angular為我們提供XHR(我們可以模擬它)的依賴注入,angular還創(chuàng)建允許我們對(duì)model進(jìn)行排序而不需要操作DOM的抽象。所以,到最后,我們可以簡(jiǎn)單地寫(xiě)一個(gè)排序方法,然后通過(guò)測(cè)試用例創(chuàng)建數(shù)據(jù)集合,供排序方法測(cè)試時(shí)使用,然后判斷結(jié)果model是否符合預(yù)期。測(cè)試無(wú)須等待XHR、者創(chuàng)建對(duì)應(yīng)的DOM和判斷函數(shù)是否正確操作DOM。angular的核心思想包含代碼的可測(cè)試性,但同時(shí)也要求我們?nèi)プ稣_的事情。angular致力于簡(jiǎn)化做正確事情的方法,但angular不是魔法,這意味著我們?nèi)绻蛔裱韵碌膸c(diǎn),我們最終可能會(huì)得出一個(gè)不可測(cè)試的應(yīng)用。

1. Dependency Inject

  有許多辦法可以獲得依賴的資源:1)我們可以使用new操作符;2)我們使用一個(gè)眾所周知的方式,被稱為” 全局單例”;3)我們可以向registry service請(qǐng)求(但我們?nèi)绾稳〉靡粋€(gè)registry?可以查看后面的章節(jié));4)我們可以期待它會(huì)被傳遞過(guò)來(lái)。

  上面列出的方法中,只有最后一個(gè)是可測(cè)試的,讓我們看看為什么:

1) Using the new operator

  使用new操作符時(shí)基本上沒(méi)有錯(cuò)誤,但問(wèn)題是通過(guò)new調(diào)用構(gòu)造函數(shù)將會(huì)永久地將調(diào)用方與type綁定起來(lái)。舉個(gè)例子,我們嘗試實(shí)例化一個(gè)XHR對(duì)象,以讓我們可以從服務(wù)器獲得一些數(shù)據(jù)。

function MyClass() {
   this.doWork = function() {
     var xhr = new XRH();
     xhr.open(method,url,true);
     xhr.onreadystatechange = function() {…};
     xhr.send();
  }
}

  問(wèn)題來(lái)了,在測(cè)試時(shí),我們通常需要實(shí)例化一個(gè)可以返回測(cè)試數(shù)據(jù)或者網(wǎng)絡(luò)錯(cuò)誤的虛擬的XHR。通過(guò)調(diào)用new XHR(),我們永久地綁定了真實(shí)的XHR,并且沒(méi)有一個(gè)很好的方法去替代它。當(dāng)然,有一個(gè)糟糕的補(bǔ)救辦法,有很多理由可以證明那是一個(gè)糟糕的想法:

var oldXHR = XHR;
XHR = new MockXHR() {};
myClass.doWork();
//判斷MockXHR是否通過(guò)正常的參數(shù)進(jìn)行調(diào)用
XHR = oldXHR;//如果忘了這一步,很容易會(huì)發(fā)生悲催的事情。

2) Global look-up

  解決問(wèn)題的另外一個(gè)方法是在一個(gè)眾所周知的地方獲取依賴的資源。

function MyClass() {
   this.doWork = function() {
      global.xhr({…});
  };
}

  沒(méi)有創(chuàng)建新依賴對(duì)象的實(shí)例的情況下,問(wèn)題基本上與new一致,除了那個(gè)悲催的補(bǔ)丁以外,沒(méi)有一個(gè)很好的方法可以再測(cè)試時(shí)攔截global.xhr的調(diào)用。測(cè)試的最基本的問(wèn)題是global變量需要改為調(diào)用虛擬的方法而被修改。想進(jìn)一步了解它的壞處,可以參觀這里:http://misko.hevery.com/code-reviewers-guide/flaw-brittle-global-state-singletons/

  上面的代碼比較難去測(cè)試,所以我們必須修改global state:

var oldXHR = global.xhr;
global.xhr = function mockXHR(){…};
var myClass = new MyClass();
//判斷MockXHR是否通過(guò)正常的參數(shù)進(jìn)行調(diào)用
global.xhr = oldXHR;//如果忘了這一步,很容易會(huì)發(fā)生悲催的事情。

3) Service Registry

  擁有一個(gè)包含所有service的registry的話,似乎可以解決問(wèn)題,然后,在測(cè)試代碼中替換所需要的service。

function MyClass() {
   var serviceRegistry = ???;
   this.doWork = function() {
     var xhr = serviceRegistry.get(“xhr”);
    …
  };
}

  但是,serviceRegistry來(lái)自哪里?if it is: * new-ed up, the the test has no chance to reset the services for testing * global look-up, then the service returned is global as well (but resetting is easier, since there is only one global variable to be reset)(這里后面的文字跟亂碼一樣……沒(méi)看懂)

  根據(jù)這個(gè)方法,將上面的Class修改為如下的方式:

var oldServiceLocator = global.serviceLocator;
global.serviceLocator.set('xhr', function mockXHR() {});
var myClass = new MyClass();
myClass.doWork();
//判斷MockXHR是否通過(guò)正常的參數(shù)進(jìn)行調(diào)用
global.serviceLocator = oldServiceLocator; //如果忘了這一步,很容易會(huì)發(fā)生悲催的事情。

4) Passing in Dependencies

  最后,依賴資源可以被傳入。

function MyClass(xhr) {
   this.doWork = function() {
     xhr({…});
  };
}

  這個(gè)是首選的方式,因?yàn)榇a無(wú)須理會(huì)xhr是從哪來(lái)的,也不關(guān)心誰(shuí)創(chuàng)建了傳進(jìn)來(lái)的xhr。因此,類的創(chuàng)建者與類的使用者可以分開(kāi)編碼,這將創(chuàng)建的責(zé)任從邏輯中分離出來(lái),這就是依賴注入的概述。

  這個(gè)class很容易測(cè)試,在測(cè)試中我們可以這樣寫(xiě):

function xhrMock(args) {…}
var myClass = new MyClass(xhrMock);
myClass.doWrok();
//做一些判斷……
通過(guò)這個(gè)測(cè)試代碼,我們可以意識(shí)到?jīng)]有任何全局變量被破壞。

  angular附帶的dependency-injection(http://chabaoo.cn/article/91775.htm),通過(guò)這種方式編寫(xiě)的代碼,更加容易編寫(xiě)測(cè)試代碼,如果我們想編寫(xiě)可測(cè)試性強(qiáng)的代碼,我們最好使用它。

2. Controllers

  邏輯使每一個(gè)應(yīng)用都是唯一的,這就是我們想去測(cè)試的。如果我們的邏輯里面混雜著DOM的操作,這將會(huì)跟下面的例子一樣難測(cè)試:

function PasswordController() {
  // 獲取DOM對(duì)象的引用
  var msg = $('.ex1 span');
  var input = $('.ex1 input');
  var strength;

  this.grade = function() {
     msg.removeClass(strength);
     var pwd = input.val();
     password.text(pwd);
     if (pwd.length > 8) {
        strength = 'strong';
     } else if (pwd.length > 3) {
        strength = 'medium';
     } else {
        strength = 'weak';
     }
    msg.addClass(strength).text(strength);
  }
}

  上面的代碼在測(cè)試時(shí)會(huì)遇到問(wèn)題,因?yàn)樗枰覀兊膱?zhí)行測(cè)試時(shí)候,需要有正確的DOM。測(cè)試代碼會(huì)如下:

var input = $('<input type="text"/>');
var span = $('<span>');
$('body').html('<div class="ex1">').find('div').append(input).append(span);
var pc = new PasswordController();
input.val('abc');
pc.grade();
expect(span.text()).toEqual('weak');
$('body').html('');

  在angular中,controller嚴(yán)格地將DOM操作邏輯分離出來(lái),將大大降低編寫(xiě)測(cè)試用例的難度,看看下面的例子:

function PasswordCntrl($scope) {
  $scope.password = '';
  $scope.grade = function() {
     var size = $scope.password.length;
     if (size > 8) {
          $scope.strength = 'strong';
     } else if (size > 3) {
          $scope.strength = 'medium';
     } else {
          $scope.strength = 'weak';
     }
  };
}

  測(cè)試代碼直截了當(dāng):

var pc = new PasswordController($scope);
pc.password('abc');
pc.grade();
expect($scope.strength).toEqual('weak');

  值得注意的是,測(cè)試代碼不僅僅更加間斷,而且更加容易追蹤。我們一直說(shuō)測(cè)試用例是在講故事,而不是判斷其他不相關(guān)的東西。

3. Filters

  filter(http://docs.angularjs.org/api/ng.$filter)是用于將數(shù)據(jù)轉(zhuǎn)換為對(duì)用戶友好的格式。它們很重要,因?yàn)樗鼈儗⑥D(zhuǎn)換格式的責(zé)任從應(yīng)用邏輯中分離出來(lái),進(jìn)一步簡(jiǎn)化了應(yīng)用邏輯。

myModule.filter('length', function() {
  return function(text){
     return (''+(text||'')).length;
  }
});

var length = $filter('length');
expect(length(null)).toEqual(0);
expect(length('abc')).toEqual(3);

4. Directives

5. Mocks

6. Global State Isolation

7. Preferred way of Testing

8. JavascriptTestDriver

9. Jasmine

10.   Sample project

 后續(xù)繼續(xù)更新相關(guān)文章,謝謝大家對(duì)本站的支持!

相關(guān)文章

  • AngularJS 中文API參考手冊(cè)

    AngularJS 中文API參考手冊(cè)

    本文主要介紹AngularJS API,這里對(duì)AngularJS的指令,事件,全局API等做中文翻譯,希望能幫助有需要的小伙伴
    2016-07-07
  • AngularJS學(xué)習(xí)筆記(三)數(shù)據(jù)雙向綁定的簡(jiǎn)單實(shí)例

    AngularJS學(xué)習(xí)筆記(三)數(shù)據(jù)雙向綁定的簡(jiǎn)單實(shí)例

    這篇文章主要介紹了AngularJS學(xué)習(xí)筆記(三)數(shù)據(jù)雙向綁定的簡(jiǎn)單實(shí)例,詳解數(shù)據(jù)雙向綁定實(shí)例的相關(guān)資料,需要的朋友可以參考下。
    2016-11-11
  • AngularJS使用ng-repeat指令實(shí)現(xiàn)下拉框

    AngularJS使用ng-repeat指令實(shí)現(xiàn)下拉框

    這篇文章主要介紹了AngularJS使用ng-repeat指令實(shí)現(xiàn)下拉框的相關(guān)資料,非常不錯(cuò),感興趣的朋友一起看下吧,需要的朋友可以參考下
    2016-08-08
  • 激動(dòng)人心的 Angular HttpClient的源碼解析

    激動(dòng)人心的 Angular HttpClient的源碼解析

    這篇文章主要介紹了Angular HttpClient的源碼解析,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-07-07
  • 詳解Ubuntu安裝angular-cli遇到的坑

    詳解Ubuntu安裝angular-cli遇到的坑

    這篇文章主要介紹了詳解Ubuntu安裝angular-cli遇到的坑,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-09-09
  • angular.bind使用心得

    angular.bind使用心得

    這篇文章主要介紹了angular.bind使用心得,以及個(gè)人對(duì)于angular.bind的理解,這里分享給大家,希望大家能夠喜歡。
    2015-10-10
  • AngularJS表單基本操作

    AngularJS表單基本操作

    這篇文章主要為大家詳細(xì)介紹了AngularJS表單基本操作的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-01-01
  • 使用Angular CLI生成路由的方法

    使用Angular CLI生成路由的方法

    這篇文章主要介紹了使用Angular CLI生成路由的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-03-03
  • Angular組件間通信的新解決方案詳解

    Angular組件間通信的新解決方案詳解

    本文通過(guò)對(duì)比幾種Angular組件間的通信方式,給大家介紹了一種新的Angular組件間通信的解決方案,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • AngularJS解決ng-if中的ng-model值無(wú)效的問(wèn)題

    AngularJS解決ng-if中的ng-model值無(wú)效的問(wèn)題

    本篇文章主要介紹了AngularJS解決ng-if中的ng-model值無(wú)效的問(wèn)題,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06

最新評(píng)論