概要
Angular のサービスクラスのユニットテストに関して調べた。かつ、グローバルでモックを定義する方法も考慮。
環境
MacOS Angular.js v8.x.x
情報収集
Angular の公式ドキュメントにテストに関するページがある。
- Testing https://angular.io/guide/testing
今回はサービスクラスのテストを行うので、以下のセクションを見た。
- Testing > Service Tests https://angular.io/guide/testing#service-tests
かつ、テストの Tips に関するセクションも見た。
- Testing > Useful tips https://angular.io/guide/testing#useful-tips
テストについて
Angular way に則って、 Karma/Jasmine を使うのが良さそう。
設定ファイルは ./karma.config.js
と ./src/test.ts
を利用。
$ ng test
でテスト起動(watch オプションもあり)。CLIでもブラウザでも、テストの結果が見られる。
Service のテストについて
Service のテストは、Class を import してきて初期化してメソッドを実行する、とかでも全然OK。
ただし、Angular の DI を活かして実際の使い方に近づけた方がよい。そこで使えるのが TestBed
というクラス。
モックの作成について
Angular というより、Karma/Jasmine の話かな。Service が依存している関数やクラスのモックを作る必要がある。
global なモックは外部ファイルに定義し、 karma.config.js
の files
という項目で読み込ませる方法がある。ここで言う読み込みとは、 index.html
で <script />
読み込みしたのと同等の効果がある。
files
は js ファイルに対応可、 ts ファイルには対応不可。
テストファイル内においては、 spyOn
というグローバル関数でメソッドの置き換えが可能。
// localstorage.mock.ts const mockGetItem = () => { /* some code */ } spyOn(localStorage, "getItem").and.callFake(mockGetItem)
参考: Karma config with global variables - gist.github.com
テストの作成
テストファイルの内容はこんな感じになりそう。
import { 必要なもの } from "path/to/thing" /* グルーバルスコープで定義するもの */ let service; let mockData; describe("Class Name", () => { // 各テストの共通前処理 beforeEach(() => { // サービス初期化 TestBed.configureTestingModule({ providers: [ServiceClass] }); service = getTestBed().get(ServiceClass); // 関数置き換え spyOn(console, 'log').and.callFake(() = { /* 置き換え内容 */ }}); // モックデータのリセット mockData = {} }) // メソッドテスト describe("#Method Name", () => { it("foo", () => { /* テスト内容 */ }) }) })