はじめに
プライベートで書いているスクリプトのテストをしたいが、メンテナンスするパッケージを増やしたくないと思い、
Node.js v18 から標準で使えるようになったNode.js Test Runner を使ってテストできないかを調べていました。
調べてみたところ、モジュールのモックをする方法で少し詰まったので、その解決方法を書きます。
なお、今回試すのは CJS です。
やりたいテスト
今回やりたかったテストは、テスト対象のモジュール内で使用されている別のモジュールをモックするようなテストです。
例として、以下のスクリプトを使います。
add.js
exports.add = (a, b) => {
return a + b;
};
mul.js
const { add } = require("./add");
exports.mul = (a, b) => {
let result = 0;
for (let i = 0; i < b; i++) {
result = add(result, a);
}
return result;
};
そして、今回テストしたいのはmul
関数で、add
関数をモックしたいとします。
この場合であれば、mock.method
関数を使い、以下のようにモックすることができます。
mul.test.js
const { test, mock } = require("node:test");
const assert = require("node:assert");
// `mul`よりも先に`add`をモックする必要がある
const addModule = require("./add");
mock.method(addModule, "add", (a, b) => {
return 1;
});
const { mul } = require("./mul");
test("mul", () => {
assert.equal(mul(2, 3), 1);
});
同様にビルトインモジュールなどもモックできます。
readFileSync.test.js
const { test, mock } = require("node:test");
const assert = require("node:assert");
const fs = require("node:fs");
mock.method(fs, "readFileSync", (path) => {
return "hoge";
});
test("readFileSync", () => {
assert.equal(fs.readFileSync("sample.txt"), "hoge");
});
なお、モックしたいモジュールがmodule.exports
で定義されている場合、mock.method
ではモックできないようです。(いろいろ試したけど、できる方法を見つけれなかった。Module._load
でモック関数を返すしか思いつかなかった。)