最近新換了一個項目,去的時候項目已經作了兩個月了,由於前期趕功能,沒有對單元測試作要求,CI/CD 的時候也沒有強制跑單元測試。因此雖然有用 Angular CLI 自動生成的測試文件,可是基本上都是測試不經過。
項目作久了,人員變更多,新來的成員對以前的業務邏輯不清不楚,稍不注意就會破壞以前的功能;業務複雜了,隨便增長或者修改一點點功能均可能引發不易被察覺的 BUG。做爲一個敬業的開發,不上單元測試怎麼行。因此,就有了一個修復已有單元測試的任務。
修復已有測試文件的思路很簡單:寫個 TestingModule 把經常使用的依賴 mock 掉,再引入到須要的文件中就好了;不經常使用的依賴,在各自的文件中 mock 掉就行了。
然而實際操做起來的時候,Karma 早早挖好坑等這了。有些測試文件單跑沒有問題,總體跑得時候就報錯,測試結果及其不穩定;karma 的報錯信息又特別難讀懂,不少時候根本定位不到究竟是哪裏出了問題。再加上 Karma 須要先把 Angular 應用編譯以後再在瀏覽器中跑測試,總體時間也比較慢,修復的過程一直處於抓狂的邊緣。
總體測試跑起來的時候難以定位測試出錯的定位,怎麼辦呢,那就讓跑整個測試的時候各個文件之間也沒有依賴能夠單獨跑好了,因此就想到了 Jest。實踐證實,在 Angular 中, Jest 大法也很是好使。html
前面也說過了,在修復測試的過程當中,karma 遇到了各類各樣的問題。歸結起來大概就是:git
那麼對比而言,Jest 在上面這些方面都有很好的表現:github
除了這些,Jest 還有的好處有:web
第一步,你須要相關依賴包:chrome
npm install --save-dev jest jest-preset-angular @types/jest
其中:npm
第二步,你須要在 package.json 中對 Jest 進行配置:json
"jest": { "preset": "jest-preset-angular", "setupFilesAfterEnv": ["<rootDir>/src/setupJest.ts"] }
其中,preset
聲明瞭預設,setupFilesAfterEnv
配置了 Jest setup 文件的地址,能夠包含多個文件,這裏設置的是項目根目錄下的 src/setupJest.ts
。瀏覽器
第三步,在 src 目錄下建立上一步中設置的 setup 文件 setupJest.ts
session
import 'jest-preset-angular'; // jest 對於 angular 的預配置 import './jestGlobalMocks'; // jest 全局的 mock
第四步,在 src 目錄下建立 jestGlobalMocks.ts
文件,並加入相關的全局的 mock,如下是一個例子:app
const mock = () => { let storage = {}; return { getItem: key => key in storage ? storage[key] : null, setItem: (key, value) => storage[key] = value || '', removeItem: key => delete storage[key], clear: () => storage = {}, }; }; Object.defineProperty(window, 'localStorage', {value: mock()}); Object.defineProperty(window, 'sessionStorage', {value: mock()}); Object.defineProperty(window, 'getComputedStyle', { value: () => ['-webkit-appearance'] });
能夠看到這個例子中 mock 了 window 上的對象,這是由於 jsdom 並無實現全部的 window 上的對象和方法,因此有時咱們須要本身給 window 打個補丁。
在這裏 mock localStorage
是可選的,若是咱們在代碼中並無使用。可是 mock getComputedStyle
是必須的,由於 Angular 會檢查它在哪一個瀏覽器中執行。若是沒有 mock getComputedStyle
,咱們的測試代碼將沒法執行。
接下來,咱們就能夠在 package.json 的 script 中配置 test 的命令了:
"test": "jest", "test:watch": "jest --watch",
其中 test
只跑一次測試,test:watch
能夠檢測文件變化,跑當前有修改的文件的相關測試。
此時,在命令行中運行測試命令,就應該可以順利把測試跑起來並經過了。若是沒有經過,多是由於咱們在 src/tsconfig.spec.json
中的 file 配置中有 test.js
的配置,這是 Karma 的 setup 文件,刪掉這行配置並刪除對應的文件,(src/tsconfig.app.json
中出現的 test.js
也可一併刪除),從新跑一遍測試命令:
npm run test
至此,Jest 測試環境就算順利搭建好了。若是你對代碼有潔癖,接下來,你還能夠刪除 Karma 的相關代碼,將測試所有轉爲 Jest。
刪除相關依賴包(@types/jasmine @types/jasminewd2 jasmine-core jasmine-spec-reporter 由於在 e2e 測試中有使用因此不能刪除):
npm uninstall karma karma-chrome-launcher karma-coverage-istanbul-reporter karma-jasmine karma-jasmine-html-reporter
src/karma.config.js
src/tsconfig.spec.json
中 compilerOptions.type
的配置移除 jasmine, 加上 jest。至此,你已經刪除了全部與 Karma 相關的代碼。你甚至還能將測試斷言換成 jest 的風格。
查看最後生成的代碼庫和相關文件配置
參考: