create-react-app や vue-cli で作成したアプリケーションは、簡単な設定で Jest によるテストを実行することができます。
今回は特に vue-cli でプロジェクトを作成して、Jest を使っていきます。
vue-cli のインストール
まず vue-cli をグローバルにインストールします。ver3 を使用します。
https://cli.vuejs.org/guide/installation.html
npm install -g @vue/cli
vue --version # 3 と出れば OK
GUI で Vue プロジェクトを作成する
vue ui
create project -> preset -> Manual を選択 -> 以下くらいを選択する
- babel (必須)
- Linter/Formatter
- Using testing (必須)
- Use config files (強く推奨)
Configuration
- ESLint + Prettier をおすすめ
- Unit testing solution は Jest で指定
で作成。
するとプロジェクトができます。
デフォルトで用意されたテストを走らせてみる
npm run test:unit
すると以下のようにテストが実行されて通ったことがわかります。
.spec.js というファイル名のものがテストが書かれたファイルです。
このテストに書かれたコードの概要は以下です。
// vue のテスト用のモジュール
import { shallowMount } from "@vue/test-utils";
// 実際に書かれているコンポーネント
import HelloWorld from "@/components/HelloWorld.vue";
// テストを宣言していく
describe("HelloWorld.vue", () => {
it("renders props.msg when passed", () => {
const msg = "new message";
// コンポーネントへ、テストを簡単にするためのラッピングをする
const wrapper = shallowMount(HelloWorld, {
// その際にコンポーネントに対して props を与える
propsData: { msg }
});
// テスト結果がどうなるべきかを定義する
// コンポーネント内のテキストが、msg = "new message" になっていることを期待
expect(wrapper.text()).toMatch(msg);
});
});
テストを watch 状態で走らせる
やってみたらできただけで、マニュアルを見たわけではないのですが、以下のように package.json の script を変えれば、watch モードで Jest が走ります。変更があったテスト、テストに関係するファイルの変更を感知して、それだけを実行してくれます。
{
"script": {
"test:unit": "vue-cli-service test:unit --watch"
}
}
axios でフェッチする API テストを書く
まずは axios をインストール
npm i axios
テストを書く。
ポイントは async ファンクションにすること。これによって axios 等プロミスベースで非同期通信するアプリケーションのテストも、簡単に書くことができる。
import axios from "axios";
// async ファンクションにする
test("fetch test", async () => {
const url = "https://api.myjson.com/bins/159wqn";
// await でとってくるのを待つ
const { data } = await axios.get(url);
// これはしなくてもいいが中身をみとく
console.log(data);
// オブジェクトに member というプロパティがあることを期待
// なければエラーが出る
expect(data).toHaveProperty("member");
});
Localstorage を使う
vue-cli で作ったアプリケーションの場合はうまくいくのですが、自分で webpack 等を設定した場合には、たいていの場合 localStorage が使えないと思います。自分はそうなりました。
そのためには jest-localstorage-mock を使います。
npm i -D jest-localstorage-mock
Jest の設定ファイルに以下を追加。
module.exports = {
//
setupFiles: ['<rootDir>/test/unit/setup', 'jest-localstorage-mock'],
//
};
これで localStorage にもアクセスできます。
import axios from "axios";
// async ファンクションにする
test("fetch test", async () => {
const url = "https://api.myjson.com/bins/159wqn";
// await でとってくるのを待つ
const { data } = await axios.get(url);
// これはしなくてもいいが中身をみとく
console.log(data);
// オブジェクトに member というプロパティがあることを期待
// なければエラーが出る
expect(data).toHaveProperty("member");
// localStorage にもアクセスできる
localStorage.setItem("item", "testItem");
const storageItem = localStorage.getItem("item");
console.log(storageItem);
});
あとは Jest のドキュメントで、expect().toBe 等々をチェックしてください。
snapShot を取る
API で取得した値が常に一定かどうか、スナップショットを取ることで、違いが発生した時にエラーを吐くようにできます。
これでもしバックエンド側がフロント開発チームに告知なく API を変更したとしても、そのエラーに気づくことができます。
import axios from "axios";
// async ファンクションにする
test("fetch test", async () => {
const url = "https://api.myjson.com/bins/159wqn";
// await でとってくるのを待つ
const { data } = await axios.get(url);
// これはしなくてもいいが中身をみとく
console.log(data);
// オブジェクトに member というプロパティがあることを期待
// なければエラーが出る
expect(data).toHaveProperty("member");
localStorage.setItem("item", "testItem");
const storageItem = localStorage.getItem("item");
console.log(storageItem);
// snapShot を取得する
expect(data).toMatchInlineSnapshot();
});
まとめ
Jest で非常に簡単にテストを実行することができました。
さらに Vuex やコンポーネントのテストの記事についても今後書きたいと思います。