🔥

【Deno】DenoTestでDIされたクラスをテストする

2023/11/14に公開

Deno test使用して、依存性逆転を実装したクラスをモック化してテストする方法を解説します。

アプリケーション実装

  • ScriptLangを上位クラスとして実装
  • interfaceによるコンストラクタインジェクションで、具象クラスに依存しないように設計
  • 具象クラスはimplementsで詳細の実装を強制
    phpとLaravel、typescriptとExpressとかの仕様変更にも閉じた変更対応が可能
export class ScriptLang {
    private scriptLang: ScriptLangInterface;

    constructor(scriptLang: ScriptLangInterface) {
        this.scriptLang = scriptLang
    }

    renderLangName(): string {
       console.log(this.scriptLang.getLangName())
       return this.scriptLang.getLangName()
    } 

    renderFrameworkName(): string{
        console.log(this.scriptLang.getFrameworkName())
        return this.scriptLang.getFrameworkName()
    }
}

export interface ScriptLangInterface {
    name: string;
    framework: string;

    getLangName(): string;
    getFrameworkName(): string;
}

class Ruby implements ScriptLangInterface {
    public name: string;
    public framework: string;

    constructor(name: string, framework: string) {
        this.name = name
        this.framework = framework
    }

    getLangName(): string {
        return this.name
    }

    getFrameworkName(): string {
        return this.framework
    }

}

const scriptLangInstance = new ScriptLang(new Ruby('Ruby', 'Rails'))
scriptLangInstance.renderLangName()
scriptLangInstance.renderFrameworkName()
% deno run scriptLang.ts
Ruby
Rails

DenoTest実装

テスト対象のコードが完成したので、.test.tsファイルを実装します。

  • DIによってロジックがScriptLang classにまとまっているので、モックによるテストデータの作成が可能
  • 上位クラスのメソッドをテスト
class MockScriptLang implements ScriptLangInterface {
    public name = "mock langName"
    public framework = "mock frameworkName"

    getLangName(): string {
        return this.name
    }

    getFrameworkName(): string {
        return this.framework
    }
}

const scriptLang = new ScriptLang(new MockScriptLang())

Deno.test("test renderLangName", () => {
    assertEquals(scriptLang.renderLangName(), "mock langName")
})

Deno.test("test renderFrameworkName", () => {
    assertEquals(scriptLang.renderFrameworkName(), "mock frameworkName")
})
% deno test
Check file:/src/scrpitLang/scriptLang.test.ts
Ruby
Rails
running 2 tests from ./scriptLang.test.ts
test renderLangName ...
------- output -------
mock langName
----- output end -----
test renderLangName ... ok (1ms)
test renderFrameworkName ...
------- output -------
mock frameworkName
----- output end -----
test renderFrameworkName ... ok (0ms)

ok | 2 passed | 0 failed (3ms)

メソッドの返却値と正常系の値が一致しているので、テストが成功しました。

Discussion