銀の弾丸

プログラミングに関して、いろいろ書き残していければと思っております。

mochaとBabelでESモジュールをテストする

f:id:takamints:20181110123153j:plain

npm内のESモジュールをmochaでテストしようとしたのですが、上手くいかない。 Babelが必要なんですね。mochaのテストスクリプトをbabelで変換しないと import / export が構文エラーになってしまうのです。

事前に変換しなくても、@babel/register を使ってmocha実行時に変換しながらテストできるらしいのですが、 そのやり方を調べてみると、断片的な情報がバラバラとある状態で「ココだけ見てやったらバッチリOK」ってな情報源には出会えずじまい。 あっちやこっちを見ながら最終的には何とかなりましたが、結構苦労したので備忘録としてまとめてここに書いておきます。



前提条件

  • 使用するBabelのバージョンは7。
  • テストランナーは mocha。
  • テストはnode.jsで動かします(ブラウザで行うテストじゃないです)。
  • テスト対象はnpm内の ESモジュールのクラスです。

必要なモジュール

上記の変換を行う為に最低限必要なモジュールは以下4つ。 各モジュールのバージョンは現在確認したワタシの環境のものです。おそらく現時点での最新バージョン。

  • @babel/core - 7.3.4
  • @babel/register - 7.0.0
  • babel-preset-env - 1.7.0
  • mocha - 6.0.2

飽くまでも最低限のモジュールです。ほかに必要になるモジュールがあるかもしれません。 例えばワタシはアサーションchaiを使いますし、分割代入などを使う場合はまた別のが必要になったりするんじゃないかなと思います。

npmに上記モジュールをインストールするには以下のコマンドでOK。

npm i -D @babel/core @babel/register babel-preset-env mocha

注意:ここに上げた最低限のモジュールは、次項の .babelrc の記述内容に依存しているかも知れません。 そういう意味で、この記事は「こうやればできた」に過ぎないかもしれないので注意してください。 今のところこれ以上深堀をしていないので。

Babel の設定

Babelの変換を定義する .babelrc も必要です。 babel-preset-envを指定しています。 このため依存モジュールにbabel-preset-env が必要だったのだと思います。

.babelrc

{
  "presets": [
    [
      "env",
      {
        "targets": {
          "node": true
        },
        "useBuiltIns": true
      }
    ]
  ]
}


テスト対象のESモジュールとテストスクリプト

テスト対象のESモジュール

src/my-class.js

"use strict";

/**
 * MyClass.
 * @constructor
 */
export function MyClass() {}

/**
 * bar.
 * @returns {string} "foo" を返す
 */
MyClass.prototype.bar = function() {
    return "foo";
};

mochaでESモジュールをテストするスクリプト

test/my-class.test.js

※ 以下、chaiを使っているので、npm i -D chai が必要ですよ。

"use strict";
import { assert } from "chai";
import { MyClass } from "../src/my-class.js";

describe("MyClass", () => {
    describe("#bar", () => {
        it("should returns 'foo'", () => {
            assert.equal( "foo", (new MyClass()).bar() );
        });
    });
});

mocha実行時のオプション

mocha実行時に変換するためには、以下のように --require オプションで @babel/register を指定します。

mocha --require @babel/register test/**/*.test.js

テスト対象はnpmなので、package.json のscripts を以下のように設定しておけば、npm test でテスト実行できますね。

{
  ~略~
  "scripts": {
    "test": "mocha --require @babel/register test/**/*.test.js"
  }
  ~略~
}