🍟

ES6で書かれたclassをJestでテストする

2022/03/14に公開

やりたいこと

ES6に沿って書かれたフロントエンドのJavascriptライブラリをJestでテストしたい。

経緯と事前調査(読み飛ばしても大丈夫です)

Jestでテストする時、node.jsの標準であるcommonJS方式が原則です。node.jsのライブラリを書いたのであれば、commonJSでライブラリを書けば良いのですが、フロントエンドだと、そうはいきません。例えば、index.htmlに入れるindex.jsにtestdayo.jsの以下のようなclassを読み込むとします。

testdayo.js
class Test {
  constructor() {
    console.log("呼ばれたよ");
  }
}

module.exports = Test;
index.js
const Stellaria = require("./testdayo.js");

すると、こういうエラーが出ます。

Uncaught ReferenceError: require is not defined
    at index.js:9:19

じゃあ、import ~ from ~;を使えば良いのでは?とindex.jsを以下のように書くと

index.js
import Stellaria from "./testdayo.js";

次は、こういうふうに怒られます。

Uncaught SyntaxError: The requested module './testdayo.js' does not provide an export named 'default'

結局のところ、フロントエンドのJavascriptでcommonJSを使えないので、ES6に沿って書く必要があります。 つまり、以下のように書きます。

testdayo.js
class Test {
  constructor() {
    console.log("呼ばれたよ");
  }
}

export default Test;
index.js
import Stellaria from "./testdayo.js";

ここで、次の問題が出てきます。このTestクラスをテストしようと思ったら、Jestのほうで次のようなエラーが出るのです

    export default Stellaria;
    ^^^^^^

    SyntaxError: Unexpected token 'export'

当たり前ですが、JestはcommonJSにしか対応していないので、exportが分からないよと言っています。
つまり、テストしたいフロントエンドのコードをES6からcommonJSに書き換える操作が必要となります。

色々と調べた結果、以下のような記事が確認できました。

https://zenn.dev/dozo/articles/0091f1a3e790d6

https://qiita.com/irico/items/0fa0cde39b1305c4b508

これらは、コマンドをいじったり、設定ファイルを書き換えたりする操作をします。
コマンドは、あまりいじりたくないですし、設定ファイルも、ここで紹介されているのは少し複雑なので(自分の目的では無駄が多い)、Jestの公式Referenceを参考に、もう少しシンプルに書いてみました。

必要なモジュールをインストールする

JestでES6をcommonJSに変換するときに使う、モジュールをnpmでインストールします[1]Babelというものを使います。

npm i --save-dev babel-jest @babel/core @babel/preset-env

Jestで使うBabelの設定ファイルを書く

Babelの設定ファイルは、とてもシンプルです。rootディレクトリ(package.jsonと同じ階層のディレクトリ)に以下のコードを書いて保存してください[1:1]

babel.config.js
module.exports = {
  presets: [["@babel/preset-env", { targets: { node: "current" } }]],
};

これだけでOKです。
ここで注意は、package.jsonの"type"を"module"にしないことです。
もしも、この設定を適用してしまうと

Error while loading config - You appear to be using a native ECMAScript module configuration file, which is only supported when running Babel asynchronously.

というエラーが出てきます。つまり、ES6のmoduleのconfigファイルが別に必要であるということです。用意すればいい話ですが、ここでは範囲外なので説明しません。

テストを動かす

あとは、テストを動かすだけです。testファイルもES6に則って書く必要があります。

hogehoge.test.js
import Test from "../testdayo.js"; //こんな感じで書く

describe("Test making instance", () => {
  test("Test making instance", () => {
    const test = new Test();
  });
});

これを

npm run test

で動かせば、無事、以下のように通りました(テストファイルの名前は、記事と違います)。
test result

脚注
  1. Getting Started
    / JEST https://jestjs.io/docs/getting-started ↩︎ ↩︎

Discussion