日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

AngularJs学习笔记--unit-testing

發(fā)布時間:2025/4/16 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 AngularJs学习笔记--unit-testing 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

原版地址:http://docs.angularjs.org/guide/dev_guide.unit-testing

?

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

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

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

1. Dependency Inject

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

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

1) Using the new operator

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

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

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

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

2) Global look-up

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

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

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

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

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

3) Service Registry

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

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

  但是,serviceRegistry來自哪里?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)(這里后面的文字跟亂碼一樣……沒看懂)

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

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

4) Passing in Dependencies

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

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

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

  這個class很容易測試,在測試中我們可以這樣寫:

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

  angular附帶的dependency-injection(http://www.cnblogs.com/lcllao/archive/2012/09/23/2699401.html),通過這種方式編寫的代碼,更加容易編寫測試代碼,如果我們想編寫可測試性強(qiáng)的代碼,我們最好使用它。

2. Controllers

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

function PasswordController() {// 獲取DOM對象的引用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);} }

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

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操作邏輯分離出來,將大大降低編寫測試用例的難度,看看下面的例子:

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';}}; }

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

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

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

3. Filters

  filter(http://docs.angularjs.org/api/ng.$filter)是用于將數(shù)據(jù)轉(zhuǎn)換為對用戶友好的格式。它們很重要,因?yàn)樗鼈儗⑥D(zhuǎn)換格式的責(zé)任從應(yīng)用邏輯中分離出來,進(jì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

?

  沒錯,你沒有眼花……官網(wǎng)文檔居然太監(jiān)了!……期待更新……順帶說一下,Angular學(xué)習(xí)筆記—Guide系列暫告一段落!

By Lcllao.

轉(zhuǎn)載于:https://www.cnblogs.com/lcllao/archive/2012/10/18/2728785.html

《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

以上是生活随笔為你收集整理的AngularJs学习笔记--unit-testing的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。