コンパイラかく語りき

import { Fun } from 'programming'

Angular サービスクラスのユニットテスト(グローバルモック考慮)

概要

Angular のサービスクラスのユニットテストに関して調べた。かつ、グローバルでモックを定義する方法も考慮。

環境

MacOS
Angular.js v8.x.x

情報収集

Angular の公式ドキュメントにテストに関するページがある。

今回はサービスクラスのテストを行うので、以下のセクションを見た。

かつ、テストの 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.jsfiles という項目で読み込ませる方法がある。ここで言う読み込みとは、 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", () => { /* テスト内容 */ })
    })
})