environment で宣言した変数についてテストの書き方に迷ったのでメモしておく。
- Angular v15
- @testing-library/angular v13
- jest v28
environment
Angular にはローカル・本番など、環境ごとに変数を切り替える機能がある。
// src/environment/environment.{環境}.ts
export const environment = {
production: false,
foo: "FOO"
};
environment は任意のコンポーネントやサービスで参照することができる。
import { Component, Input, OnInit } from "@angular/core";
import { environment } from "src/environments/environment";
@Component({
standalone: true,
selector: "dummy",
template: `{{ env }}`,
})
export class DummyComponent implements OnInit {
@Input() name: string;
env = "";
ngOnInit(): void {
this.env = environment[this.name];
}
}
<dummy name="foo"></dummy>
// "FOO" がレンダリングされる
テストの考察
上記のコンポーネントをテストする方法として、いくつか考えてみた。
- environment を参照するサービスを宣言して DI する
- いかにもテストのためのサービスという感じで冗長な気がした
- サービスの利用が強制できないため environment を DI したり直接インポートしたりばらつきが出る
- environment のプロパティをテストコードから上書きする
- 別のテストファイルで再度 environment を参照した時の影響度が見えないので怖い
- 上書き禁止のために as const したら破綻する
- environment.test.ts を追加しテスト環境の設定を切り分ける
- 1 パターンしか作れない
.... どれもイマイチ。
採用したテストコード
結果、Jest のモジュールモックを使うことにした。
import { render } from "@testing-library/angular";
import { screen } from "@testing-library/dom";
import { DummyComponent } from "src/app/dummy.component";
jest.mock("src/environments/environment", () => ({
environment: {
foo: "FOO",
},
}));
describe("test1", () => {
it("fooは存在するのでレンダリングされる", async () => {
await render(`<dummy [name]="name"></dummy>`, {
imports: [DummyComponent],
componentProperties: { name: "foo" },
});
expect(screen.getByText("FOO")).toBeInTheDocument();
});
it("barは存在しないのでレンダリングされない", async () => {
await render(`<dummy [name]="name"></dummy>`, {
imports: [DummyComponent],
componentProperties: { name: "bar" },
});
expect(screen.queryByText("BAR")).toBeNull();
});
});
この方法なら、別のテストファイルで environment の別パターンを用意することもできる。
jest.mock("src/environments/environment", () => ({
environment: {
bar: "BAR",
},
}));
describe("test2", () => {
it("foo", async () => {
await render(`<dummy [name]="name"></dummy>`, {
imports: [DummyComponent],
componentProperties: { name: "foo" },
});
// environment に foo は存在しない
expect(screen.queryByText("FOO")).toBeNull();
});
});
同一ファイル内で複数回の jest.mock を呼べないなどベストとは言えないが、思いついた方法の中ではいちばん良さそう。他にいい方法があれば知りたい。