現状
vueの単一ページコンポーネントのテスト行う場合、
公式ドキュメントの単体テストの項に従って行った場合は、karmaが必要になります。
問題
ただKarmaを利用した場合、そのための設定が必要になってちょっと面倒です。
その上、手間をかけて設定したとしてもViewのレンダリングを含めてのテストは後回しになるケースが多く(自分の場合)、レンダリングのテストは無駄になる場合も多いため、そこにコストをかけたくありません。またKarmaの起動するコストも気になります。
解決策
.vue
ファイルをimportすることでモジュールのテストができれば良いのですが、そのままjavaファイルをimportした場合はparseできずにエラーになります。これをできるようにするのが今回のGoalです。
結論
package.jsonに以下を追加した上で
{
"devDependencies": {
"babel-core": "^6.24.0",
"vue-template-compiler": "2.2.6",
},
}
vue用のloaderを自作して、
import fs from "fs";
import path from "path";
import { parseComponent } from "vue-template-compiler";
import { transform } from "babel-core";
require.extensions[".vue"] = (module, filename) => {
const parsed = parseComponent(fs.readFileSync(filename, "UTF-8"));
const content = transform(parsed.script.content, { extends: path.resolve(".babelrc") });
module._compile(content.code, filename);
};
mocha.optsに埋め込みました。
--compilers js:babel-register,vue:babel-register
--require test/loader
こうすることで、importした場合に、vueの単一ファイルコンポーネントの<script>
タグの部分のみを解釈したcomponentが生成されます。importされたファイルは<template>
を持たないVueファイルになるので、avoriazを用いて、通常通りmountすることも可能です。
簡単な説明
require.extensions[".vue"] = (module, filename) => {
.vue
の拡張子を持つファイルを読み込んだ場合の実行されるローダーを定義します。
const parsed = parseComponent(fs.readFileSync(filename, "UTF-8"));
vue-template-compilerのparseComponentを使って、対象のvueファイルをparseします。
const content = transform(parsed.script.content, { extends: path.resolve(".babelrc") });
babel-coreのtransformを使って、es6のコードをバベります。その際に、.babelrc
を設定することで、適時変換を行います。依存関係の解決もここで行われます。
module._compile(content.code, filename);
変換されたファイルをコンパイルして実際のコンポーネントに変換します。
実際のテスト
そのまま、mochaでテストできます
import Vue from "vue";
import ExampleView from "components/ExampleView.vue";
import { mount } from "avoriaz";
describe("components/ExampleView", () => {
describe("computed", () => {
describe("hello", () => {
it("workが返される", () => {
const wrapper = mount(ExampleView, {
propsData: {
// 必要があれば設定する
},
});
const actual = "world";
assert(actual === wrapper.vm.hello);
});
});
});
私は、今のところはこれで必要十分でした。