Jestで非公開関数をテストする方法がイマイチだった
前回の続き。
結論:const を上書きできないっぽいのでrewire以外の方法を探すのが良さそう…
(追記に上げたように、Jestで動かす時にできないという条件付き)
前提
検証した時のバージョン
{ "dependencies": { "jest": "^23.6.0", "rewire": "^4.0.1" } }
モック前
テスト対象
const fs = require("fs"); const read = cb => { return fs.readFile("./text.txt", "utf-8", cb); }; module.exports = read;
テストコード
const read = require("./read.js"); test("read", done => { return read((err, text) => { expect(text).toMatch("foobar"); done(); }); });
モックしてみる(失敗)
fs.readFile
の結果をモックしたいので、こう書いてみる
テストコード2
const rewire = require("rewire"); const read = rewire("./read.js"); test("read", done => { read.__set__("fs", { readFile: (path, enc, cb) => cb(null, "foobar") }); return read((err, text) => { expect(text).toMatch("foobar"); done(); }); });
けれど結果はモック前と変わらない…
Issue当たってみると、同じ悩みを抱えてる人がいたよう。「Rewiring const is supported since 3.0.0」って言ってるけどReopenされてる。そしてReopenした人の「TypeError: Assignment to constant variable」とも違う状況なので不思議な気持ち。
モックしてみる(とりあえず成功)
Issueへの返信にもあった let
使ってみる方法を試す。テストコードは2の状態のまま。
テスト対象2
let fs = require("fs"); const read = cb => { return fs.readFile("./text.txt", "utf-8", cb); }; module.exports = read;
これでテストはPassした。でもテストのために let
にするのっておかしいし、そんな制限ある中でコード書きたくないのでrewireは使えないかな…
追記
どうやらJestとの組み合わせが良くないらしい。
リンク先ではMochaで試してるけどnodeでもMock成功した。
// run.js const rewire = require("rewire"); const read = rewire("./read.js"); read.__set__("fs", { readFile: (path, enc, cb) => cb(null, "foobar") }); return read((error, text) => { console.log({ error, text }); });
node run.js
として呼び出したらモック成功した。まあJestとの組み合わせが良くないなら選択できないんだけど、ライブラリ自体は問題ないようだったので訂正。