精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

編寫可測試的JavaScript代碼

移動開發
無論我們使用和Node配合在一起的測試框架,例如Mocha或者Jasmine,還是在像PhantomJS這樣的無頭瀏覽器中運行依賴于DOM的測試,和以前相比,我們有更好的方式來對JavaScript進行單元測試。

無論我們使用和Node配合在一起的測試框架,例如Mocha或者Jasmine,還是在像PhantomJS這樣的無頭瀏覽器中運行依賴于DOM的測試,和以前相比,我們有更好的方式來對JavaScript進行單元測試。

然而,這并不意味著我們要測試的代碼就像我們的工具那樣容易!組織和編寫易于測試的代碼需要花費一些精力和并對其進行規劃,但是在函數式編程的啟發下,我們發現了一些模式,當我們需要測試我們的代碼時,這些模式可以幫助我們避免那些“坑”。在這篇文章中,我們會查看一些有用的小貼士和模式,來幫助我們在JavaScript中編寫可測試的代碼。

保持業務邏輯和顯示邏輯分離

對于基于JavaScript的瀏覽器應用程序來說,其中一項主要工作就是監聽終端用戶觸發的DOM事件,然后通過運行一些業務邏輯并在頁面上顯示結果,以此對用戶做出反饋。在建立DOM事件監聽器的地方,有時會誘惑你編寫一個匿名函數來完成所有這些工作。這樣帶來的問題是為了測試匿名函數,你不得不去模擬DOM事件。這樣不僅會增加代碼行數,而且會增加測試運行的時間。 

 

 

 

與之相反,編寫一個有名字的函數,然后將其傳給事件處理器。通過這種方式,你可以直接針對這個有名字的函數編寫測試用例,而不用去觸發一個假的DOM事件。

這不僅僅可以應用到DOM上。在瀏覽器和Node上的很多API,都被設計成觸發和監聽事件,或者等待其它類型的異步工作完成。憑經驗說,如果你編寫了大量的匿名回調函數,那么你的代碼可能不會容易被測試。

  1. // hard to test 
  2. $('button').on('click', () => { 
  3.     $.getJSON('/path/to/data'
  4.         .then(data => { 
  5.             $('#my-list').html('results: ' + data.join(', ')); 
  6.         }); 
  7. }); 
  8.   
  9. // testable; we can directly run fetchThings to see if it 
  10. // makes an AJAX request without having to trigger DOM 
  11. // events, and we can run showThings directly to see that it 
  12. // displays data in the DOM without doing an AJAX request 
  13. $('button').on('click', () => fetchThings(showThings)); 
  14.   
  15. function fetchThings(callback) { 
  16.     $.getJSON('/path/to/data').then(callback); 
  17.   
  18. function showThings(data) { 
  19.     $('#my-list').html('results: ' + data.join(', ')); 
  20.  

對異步代碼使用回調或者Promise

在上述的示例代碼中,我們經過重構的函數fetchThings會運行一個AJAX請求,以異步的方式完成了大部分工作。這意味著我們不能運行函數并測試它是否按照我們預期的那樣運行,因為我們不知道它什么時候運行完。

解決這個問題最常見的方法,是向函數中傳遞一個回調函數作為參數,作為異步調用。這樣,在你的單元測試中,你可以在傳遞的回調函數中運行一些斷言。 

 

 

 

另外一種常見并且越來越流行的組織異步代碼方法,是使用Promise API的方式。幸運的是,$.ajax和其它大部分jQuery的異步函數已經返回了Promise對象,因此它已經涵蓋了大部分常見的用例。

  1. // 很難測試;我們不知道AJAX請求會運行多長時間 
  2.   
  3. function fetchData() { 
  4.     $.ajax({ url: '/path/to/data' }); 
  5.   
  6. //可測試的;我們傳入一個回調函數,然后在其中運行斷言 
  7.   
  8. function fetchDataWithCallback(callback) { 
  9.     $.ajax({ 
  10.         url: '/path/to/data'
  11.         success: callback, 
  12.     }); 
  13.   
  14. //同樣可測試的:在返回的Promise解析完后,我們可以運行斷言 
  15.   
  16. function fetchDataWithPromise() { 
  17.     return $.ajax({ url: '/path/to/data' }); 
  18.  

避免副作用

要編寫那些使用參數并且返回值僅僅依賴那些參數的函數,就像將數字傳入數學公式,然后取得結果。如果你的函數依賴于一些外部的狀態(例如類實例的屬性或者某些文件的內容),那么你在測試這個函數之前,就不得不去設置一些狀態,在測試用例中需要更多的設置。你不得不去認為那些正在運行的代碼不會修改同一個的狀態。 

 

 

 

同樣,你需要避免編寫那些會修改外部狀態的函數,例如向文件寫入內容或者向數據庫保存數據。這會避免一些副作用,來影響你測試其他代碼的能力。一般來說,***是將副作用和代碼控制在一起,讓“表面積”盡可能小。對于類和對象實例來說,類方法的副作用應該被限制在被測試的類實例的范圍內。

  1. // 很難測試;我們不得不設置一個globalListOfCars對象和一個名為#list-of-models的DOM結構,然后才能測試這段代碼 
  2.   
  3. function processCarData() { 
  4.     const models = globalListOfCars.map(car => car.model); 
  5.     $('#list-of-models').html(models.join(', ')); 
  6.   
  7. // 容易測試;我們傳遞一個參數然后測試它的返回值,而不需要設置任何全局變量或者檢查任何DOM結果 
  8.   
  9. function buildModelsString(cars) { 
  10.     const models = cars.map(car => car.model); 
  11.     return models.join(','); 
  12.  

使用依賴注入

在函數中,有一種通用的模式,可以用來降低對外部狀態的使用,這就是依賴注入 —— 將函數的所有外部需要都通過函數參數的方式傳遞給函數。

  1. // 依賴于一個外部狀態數據連接實例;很難測試 
  2.   
  3. function updateRow(rowId, data) { 
  4.     myGlobalDatabaseConnector.update(rowId, data); 
  5.   
  6. // 將數據庫連接實例作為參數傳遞給函數;很容易測試。 
  7.   
  8. function updateRow(rowId, data, databaseConnector) { 
  9.     databaseConnector.update(rowId, data); 
  10.  

使用依賴注入的一個主要好處,是你可以在單元測試中傳入mock對象,這樣就不會導致真的副作用(在這個例子中,就是更新數據庫行),你只需要斷言你的mock對象是按照期望的方式運行即可。

為每一個函數設置一個唯一的目的

將長函數分解成一系列小的、單一職責的函數。這樣我們可以更容易的去測試每一個函數是否是正確的,而不再希望一個大函數在返回結果之前就正確的做了所有的事情。

在函數式編程中,將幾個單一職責的函數拼在一起的行為稱作“組合”。Underscore.js甚至有一個名為_.compose的函數,它將一個函數列表中的函數串在一起,將每一函數的返回結果作為輸入傳遞給下一個函數。

  1. // 很難測試 
  2.   
  3. function createGreeting(name, location, age) { 
  4.     let greeting; 
  5.     if (location === 'Mexico') { 
  6.         greeting = '!Hola'
  7.     } else { 
  8.         greeting = 'Hello'
  9.     } 
  10.   
  11.     greeting += ' ' + name.toUpperCase() + '! '
  12.   
  13.     greeting += 'You are ' + age + ' years old.'
  14.   
  15.     return greeting; 
  16.   
  17. // 很容易測試 
  18.   
  19. function getBeginning(location) { 
  20.     if (location === 'Mexico') { 
  21.         return '¡Hola'
  22.     } else { 
  23.         return 'Hello'
  24.     } 
  25.   
  26. function getMiddle(name) { 
  27.     return ' ' + name.toUpperCase() + '! '
  28.   
  29. function getEnd(age) { 
  30.     return 'You are ' + age + ' years old.'
  31.   
  32. function createGreeting(name, location, age) { 
  33.     return getBeginning(location) + getMiddle(name) + getEnd(age); 
  34.  

不要改變參數

在JavaScript中,數組和對象傳遞的是引用,而非值,因此它們是可變的。這意味著當你將對象或者數組作為參數傳遞給函數時,你的代碼和使用你傳遞的對象或數組的函數,都有能力去修改內存中同一個數組或者對象。這意味著當你測試你自己的代碼時,你必須信任所有你調用的函數中,沒有任何函數會修改你的對象。每當你添加一些新的可以修改同一個對象的代碼時,跟蹤對象應該是什么樣子就會變得越來越困難,從而更難去測試它們。 

 

 

[[177541]] 

相反,當你有一個函數需要使用對象或者數組時,你應該在代碼中對待對象或者數組就像它們是只讀的。你可以根據需要創建新的對象或者數組,然后對齊填充?;蛘?,使用Undersocre或者Lodash去對傳入的對象或者數組做一個拷貝,然后再對齊進行操作。更好的選擇是,使用一些像Immutable.js這樣的工具,去創建只讀的數據結構。

  1. // 修改了傳入的對象 
  2.   
  3. function upperCaseLocation(customerInfo) { 
  4.     customerInfo.location = customerInfo.location.toUpperCase(); 
  5.     return customerInfo; 
  6.   
  7. // 返回了一個新的對象 
  8.   
  9. function upperCaseLocation(customerInfo) { 
  10.     return { 
  11.         name: customerInfo.name
  12.         location: customerInfo.location.toUpperCase(), 
  13.         age: customerInfo.age 
  14.     }; 
  15.  

在編碼之前先寫測試

在編碼之前先寫單元測試的過程被稱作測試驅動開發(TDD)。大量的開發者發現TDD非常有用。

通過先編寫測試用例,你就強迫自己從使用你代碼的開發者角度來考慮你要暴露的API,它還幫助你確保你只會編寫足夠的代碼來滿足測試用例的要求,而不要對解決方案“過度施工”,從而帶來不必要的復雜性。

在實踐中,TDD作為一條紀律,要覆蓋所有的代碼改動可能會比較困難。但是當它看上去值得嘗試的時候,這就是一個很好的方式來保證你的所有代碼都是可測試的。

總結

在編寫和測試復雜的JavaScript應用的時候,我們都知道有一些很容易遇到的“陷阱”,但我希望通過這些貼士和提醒,可以讓我們的代碼盡量簡單和函數化,我們可以做到讓測試覆蓋率很高,讓整體的代碼復雜性很低!

責任編輯:龐桂玉 來源: 前端大全
相關推薦

2013-04-15 09:02:43

JavaScriptJS

2012-12-17 13:51:22

Web前端JavaScriptJS

2022-06-07 09:30:35

JavaScript變量名參數

2014-04-21 10:14:52

PromisesJavaScript

2009-06-24 15:00:39

Javascript代

2023-01-27 14:53:03

2011-11-23 09:06:00

2011-03-04 10:11:09

JavascriptAPI

2021-10-10 23:02:49

Golang語言代碼

2018-11-08 15:50:18

前端Javascript重用性

2011-12-29 15:02:27

JavaScript

2022-06-21 12:27:12

JavaScript前端

2022-08-02 10:33:11

JavaScript代碼

2024-01-30 08:54:05

JavaScript技巧代碼

2023-09-11 11:05:49

軟件開發TDD

2012-09-17 10:35:41

JavaScriptJS代碼

2025-06-11 03:22:00

JavaScript開發前端

2015-08-27 13:11:18

JavaScript代碼

2022-08-28 19:03:18

JavaScript編程語言開發

2022-05-10 10:28:21

JavaScript代碼
點贊
收藏

51CTO技術棧公眾號

手机av免费观看| 免费看毛片的网站| 国产欧美久久久久久久久| 国内精品久久久久影院色| 久久国产精品久久国产精品| 动漫美女无遮挡免费| 午夜日韩成人影院| 一区二区三区久久| 日本不卡一区| 国产成人精品无码高潮| 米奇777在线欧美播放| xxxxx成人.com| 熟女人妻在线视频| 国产精品一区二区三区av | 久久精品国产亚洲av高清色欲| 亚洲瘦老头同性70tv| 91精品国产欧美一区二区成人| 欧美视频免费看欧美视频| 岛国在线视频免费看| 成人综合在线网站| 国产在线98福利播放视频| 日本中文字幕免费观看| 久久亚洲成人| 亚洲精品自拍视频| 五月天婷婷在线观看视频| 欧美91看片特黄aaaa| 亚洲国产视频一区二区| 亚洲一区二区三区精品在线观看| 少妇人妻一区二区| 国产一区二区三区综合| 国产精品电影在线观看| 日韩黄色精品视频| 亚洲人metart人体| 在线观看欧美成人| 成人午夜精品无码区| 久久久久毛片| 黑人巨大精品欧美一区二区免费| 一道本在线观看视频| 青青草超碰在线| 国产成人在线观看免费网站| 一本到三区不卡视频| 波霸ol色综合久久| 久久久久久69| 久久国产一区二区| 91精品国产乱码久久| 亚洲精品国产日韩| 美日韩精品免费观看视频| 级毛片内射视频| 精品按摩偷拍| 日韩写真欧美这视频| 日本www.色| 天堂资源在线| 国产精品久久久久久久久免费樱桃 | 国产成人aaa| 国产精品久久久久国产a级| 日韩欧美中文字幕一区二区| 欧美~级网站不卡| 中文字幕在线看视频国产欧美在线看完整 | 中文字幕乱伦视频| 亚洲一区二区成人| 国内偷自视频区视频综合| 欧美成人免费观看视频| 亚洲国产一区二区在线观看| 自拍亚洲一区欧美另类| 精品国产av色一区二区深夜久久| 欧美激情福利| 欧美日韩视频在线第一区| 久久九九国产视频| 深夜视频一区二区| 欧美最猛性xxxxx直播| 欧美私人情侣网站| 成人性生活av| 91久久线看在观草草青青| 国内精品视频一区二区三区| av在线导航| 久久久综合视频| 国产综合色一区二区三区| 朝桐光av在线一区二区三区| 高清成人免费视频| 亚洲一区二区在线播放| 国产伦精品一区二区三区免.费| 美女脱光内衣内裤视频久久影院| 国产欧美日韩综合精品| 97成人免费视频| 国产一区二区福利视频| 99久久国产免费免费| 99riav国产| 成+人+亚洲+综合天堂| 久久99精品久久久久子伦| 免费国产精品视频| 国产jizzjizz一区二区| 国产在线欧美日韩| 亚洲老妇色熟女老太| 久久爱另类一区二区小说| 国产精品丝袜高跟| av官网在线观看| 成人18视频在线播放| 欧美性天天影院| 9191在线观看| 中文字幕不卡的av| 国产手机视频在线观看| 爱啪视频在线观看视频免费| 在线精品国精品国产尤物884a| 久久婷婷综合色| 四虎在线精品| 欧美第一区第二区| av黄色免费网站| 狠狠色丁香婷婷综合影院| 久久精品99久久久香蕉| 日韩av在线电影| 丝袜亚洲另类丝袜在线| 成人自拍性视频| 姝姝窝人体www聚色窝| 国产日韩av一区| 波多野结衣 作品| 免费电影日韩网站| 91精品免费在线观看| 成人性生交视频免费观看| 大伊香蕉精品在线品播放| 亚洲天堂男人的天堂| 97在线观看免费高| 影音先锋亚洲一区| 国产精品网站大全| 亚洲欧美另类视频| 2021久久国产精品不只是精品| 亚洲资源视频| 伊人成综合网站| 日韩一级完整毛片| 99精品欧美一区二区| 国产精品豆花视频| 国产精品极品美女粉嫩高清在线| 亚洲AV无码乱码国产精品牛牛| 95精品视频在线| 国产日韩视频在线播放| 毛片在线导航| 黑人巨大精品欧美一区免费视频| 激情六月丁香婷婷| 国产精品sss在线观看av| www日韩中文字幕在线看| 国产成人精品网| 成人免费毛片app| 五月天综合婷婷| 日韩中文在线播放| 日韩精品视频三区| 国产无码精品一区二区| 蜜臀91精品一区二区三区| 国产呦系列欧美呦日韩呦| 酒色婷婷桃色成人免费av网| 亚洲综合精品久久| 欧美激情国内自拍| 欧美猛男同性videos| 久久这里有精品视频| 亚洲特级黄色片| 国产喷白浆一区二区三区| 亚洲中文字幕无码专区| 精品国产导航| 久久久综合av| 99精品国产99久久久久久97| **欧美大码日韩| 日韩一级免费片| 亚洲专区视频| 26uuu久久噜噜噜噜| 亚洲精品成人电影| 亚洲一级二级在线| 国产免费中文字幕| 国产午夜一区| 国产成人精品av| 国产精品四虎| 欧美日韩一区二区三区在线免费观看| 国产吃瓜黑料一区二区| 国产精品99免费看| 国产精品制服诱惑| 国产伦子伦对白在线播放观看| 91精品黄色片免费大全| 日韩av手机在线免费观看| 麻豆精品国产传媒mv男同| 中文视频一区视频二区视频三区| 成人免费福利| 精品国产网站地址| 国产农村老头老太视频| 亚洲精品国产成人久久av盗摄| 最新中文字幕日本| 色一区二区三区四区| 青青久久av北条麻妃黑人| 青青国产在线| 亚洲免费观看视频| 国模大尺度视频| 亚洲天堂成人| 精品综合在线| 久久天堂av| 久久精品这里热有精品| 国产免费的av| 亚洲国产cao| 中文字幕在线免费看线人| 日韩精品免费专区| 一本一道久久a久久精品综合| 视频欧美精品| 久久久久久成人| 免费一级在线观看播放网址| 在线观看三级视频欧美| 久久国产精品国语对白| 99久久久国产精品| 国产精品-区区久久久狼| 成人精品亚洲| 国产精品v欧美精品∨日韩| jizz内谢中国亚洲jizz| 成人一区在线观看| 亚洲不卡视频在线| 国产一区久久| 日韩av一区二区三区在线 | 久久久久久亚洲精品| 清纯唯美亚洲色图| 欧美夫妻性生活| 三级黄色在线视频| 波多野结衣中文字幕一区| 亚洲最新免费视频| 果冻天美麻豆一区二区国产| 欧美中在线观看| av在线三区| 日韩一区二区视频在线观看| 天天爽夜夜爽人人爽| 一区二区三区在线视频播放| 国产91色在线观看| 国内激情久久| 久久伊人一区二区| 色悠久久久久综合先锋影音下载| 欧美激情视频网址| 粉嫩虎白女毛片人体| 尤物国产在线观看| 最近中文字幕免费| 国模无码国产精品视频| 波多野结衣啪啪| 涩涩网在线视频| 日韩精品国产精品| 9191国产精品| 欧美成人在线免费观看| 欧美黄色一级生活片| 国产精选久久久| 日本欧美在线视频免费观看| 深夜成人福利| 国产一区不卡| 成人午夜在线播放| 日韩久久精品电影| 日本国产精品视频| 97精品国产91久久久久久| 青青草一区二区| 久久天天狠狠| 午夜久久资源| 日本欧美黄色片| 国产情侣av自拍| 动漫av在线免费观看| www.黄色com| 调教视频免费在线观看| 日韩三级视频| 99久久精品免费看国产免费软件| 欧美日韩国产高清一区二区| 欧美精品九九久久| 99国产在线| 日本免费成人网| 免费黄色在线播放| 久久精品99北条麻妃| 色老头在线观看| 国产精品一区二区av日韩在线| 国产日本精品| 国产精品国产三级国产有无不卡 | 中文字幕久热精品在线视频| 国产精品久久99久久| 日韩久久久久久久久久久久| 熟女人妻一区二区三区免费看| 欧美精品一二三四区 | av资源中文在线| 91福利精品在线观看| 日韩成人午夜精品| 欧洲国内综合视频| 久久69精品久久久久久国产越南| 欧美a级黄色大片| 99tv成人影院| 国产精华一区二区三区| 成人精品毛片| 欧美激情第六页| 亚洲精品动态| 中文字幕在线亚洲三区| 欧洲精品99毛片免费高清观看| 国产精品二区在线观看| 丁香五月缴情综合网| av一区二区三区四区电影| 欧美黑粗硬大| 91视频8mav| 97久久精品一区二区三区的观看方式| 成人高清视频观看www| 视频在线观看免费高清| av资源在线免费观看| 国产三级电影在线观看| 日本成人精品| 久久er精品视频| 色婷婷久久久亚洲一区二区三区| 最近2019免费中文字幕视频三| 俄罗斯精品一区二区三区| 青青草精品视频在线| 亚洲精品一区二区三区影院忠贞| 牛牛热在线视频| 日韩中文av| 99亚偷拍自图区亚洲| 亚洲黄一区二区| 欧美精品久久| 免费中文字幕日韩| 一区二区乱子伦在线播放| 欧美日韩精品免费观看视完整| 久久久9色精品国产一区二区三区| 国产精品婷婷| 亚洲午夜国产一区99re久久| 久久久av免费| wwwjizzjizzcom| 午夜视频福利在线| 久久国产人妖系列| 黄www在线观看| 国产精品日本| 在线观看av免费观看| 久久精品国产**网站演员| av在线免费观看不卡| 国产高清在线精品| 性の欲びの女javhd| 亚洲一区二区三区四区的| 成人黄色激情视频| 亚洲第一免费播放区| 欧美偷拍视频| 欧美成在线视频| 成人午夜亚洲| 91一区二区三区| 青草国产精品| 国产午夜福利在线播放| 视频一区二区三区在线| 777777777亚洲妇女| 免费成人在线电影| 91亚洲国产精品| 成人91在线| 欧美色图另类小说| gogo大尺度成人免费视频| 国产精品一区二区三区免费视频 | 国产91久久婷婷一区二区| 国内不卡的一区二区三区中文字幕 | 日韩欧美亚洲另类| 成人精品国产一区二区4080| 国产成人无码一区二区在线观看| 亚洲三级小视频| www.伊人久久| 欧美变态口味重另类| 黄色影院在线播放| 欧美在线欧美在线| 久久丝袜视频| 日韩精品一区在线视频| 国产盗摄女厕一区二区三区| 俄罗斯毛片基地| 亚洲少妇中出一区| 在线免费a视频| 亚洲欧美日本精品| 超碰激情在线| 国产欧美韩日| 国内亚洲精品| 久久午夜夜伦鲁鲁一区二区| av一区二区久久| 麻豆chinese极品少妇| 一本色道亚洲精品aⅴ| 天堂中文在线视频| 午夜精品久久久久久久男人的天堂| 久久免费精品| 五月天激情图片| 国产suv精品一区二区883| 黄色a一级视频| 色欲综合视频天天天| 视频一区二区三区在线看免费看| 欧美国产日韩视频| 精品国产午夜肉伦伦影院| 少妇人妻无码专区视频| 奇米777欧美一区二区| 国产一级免费片| 亚洲成人av福利| 深夜福利视频网站| 欧洲永久精品大片ww免费漫画| 亚洲第一福利专区| 无人在线观看的免费高清视频 | www.亚洲精品| 久久免费小视频| 亚洲国产精品系列| 日本韩国欧美| 亚洲欧洲一区二区福利| 狠狠狠色丁香婷婷综合久久五月| 91成人福利视频| 欧美成人a在线| 亚洲最新无码中文字幕久久| 日韩av影视| 国产一区二区三区久久悠悠色av| japanese在线观看| 色综合久久久久久久| 免费黄网站在线| 99理论电影网| 免费精品视频| 国产av自拍一区| 日韩欧美一级二级三级| 蜜桃av.网站在线观看|