昨天我們說說了關於CI/CD之中的對於檢驗的需求與要求,今天我們來講講Unit Test吧
在Angular原本内嵌的的測試元件是使用karma+jasmine進行測試的,karma負責建構起瀏覽器測試環境,jasmine負責進行檢驗的實作
這樣子的運作得以讓我們在正式環境之中可以運行我們的函式,以及有個GUI介面來讓我們看到測試過程與結果
但最後Angular開發團隊在眾多社群的回饋之中,歸納整理了大家對於調整優化的需求,其中有一項就是建構一個實體的測試環境太過臃腫與肥大
想想看,當我們要在CI的pipe執行過程中,我們必須先起一個環境,起了環境之後才能進行測試
這樣子的架構流程對於CI的流程來說可以說是非常致命的
也因此Angular@16中,Angular開發團隊表示他們正在添加對於Jest的初步嘗試與支援。
Jest 最初由 Facebook 開發,並且已被廣泛用於測試 React 應用程序,但它同樣適用於測試其他 JavaScript 項目。他可以更加直接的進行外部引用Service與pipe的Mask與Spy,這點就非常幫助我們在CI的流程上進行檢核了
接下來我們來說說怎麼在Angular16安裝與實作Jest
首先,我們先把karma-serious與jasmine都先在packahe.json移除掉,然後再重新npm i
一次
然後我們來安裝他吧
npm install --save-dev jest jest-preset-angular @types/jest
我們這樣子就完成了安裝,接下來則是調整參數,首先先宣告npm run
的指令
"test": "jest --verbose",
"test:coverage": "jest --coverage",
"test:watch": "jest --watch",
然後我們在我們的跟目錄建立一個jest.config.ts
import type { Config } from 'jest';
const config: Config = {
preset: 'jest-preset-angular',
setupFilesAfterEnv: ['<rootDir>/setup-jest.ts'],
globalSetup: 'jest-preset-angular/global-setup',
moduleNameMapper: {
'^src/(.*)$': '<rootDir>/src/$1',
},
};
export default config;
並在tsconfig.spec.json
之中在compilerOptions
宣告type
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/spec",
"types": [
"jest" <--這裡
]
},
"include": [
"src/**/*.spec.ts",
"src/**/*.d.ts",
"**/*.spec.ts"
]
}
最後的最後,我們一樣在root創建一個setup-jest.ts
用它來宣告jest-preset-angular
並將其實作在我們的專案之中
import 'jest-preset-angular/setup-jest';
window.open = jest.fn();
就這樣,我們完成了安裝,接下來我們來看看簡單的我們怎麼實作我們的環境建置
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [SalesAgreementComponent, ReactiveFormsModule, FormsModule],
providers: [
provideHttpClient(),
provideHttpClientTesting(),
provideMockStore({}),
MessageService,
],
}).compileComponents();
});
我們可以看到有些在app.config.ts的內容已經可以直接注入在這裡,進行全局Application的注入
另外則是進行我們的Component的Inject的mock
beforeEach(() => {
mockSalesAgreementService = {
updateSaleItem: jest.fn(),
};
windowSpy = jest.spyOn(window, 'window', 'get');
fixture = TestBed.createComponent(SalesAgreementComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
至於我們的unit test則是可以這樣來做第三方套件的測試
it('submit 發送訊號後跳出訊息', () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const messageServiceSpy = jest.spyOn(component['messageService'] as any, 'add');
...
expect(messageServiceSpy).toHaveBeenCalledTimes(1);
});
金天我們簡單講了Unit test 明天我們將會講講e2e test