プライベート関数のテストとモック化をしよう
単体テストを行う際に、プライベートな関数をテストすることはほとんどありませんが、なにかしら仕様をテストする際など、プライベート関数をテストしたいときがあります。Jestでプライベート関数をテストする方法をまとめていきます。
babel-plugin-rewireをインストール
はじめにパッケージをインストールします。
terminal
$ npm install --save-dev babel-plugin-rewire
次にbabel.config.js
に、このプラグインを追加します。
babel.config.js
module.exports = {
presets: [["@babel/preset-env", { targets: { node: "current" } }]],
env: {
test: {
plugins: ["babel-plugin-rewire"],
},
},
};
実際にプライベートな関数をテストしてみる
下記のgreeter.jsのexportをしていない、プライベートなcapitalize関数
をモック化とテストします。引数で与えた文字列の1文字目を大文字にして返す関数です。
greeter.js
const capitalize = (str) => {
return str.slice(0, 1).toUpperCase() + str.slice(1, str.length);
};
export const greet = (name) => {
const capitalizedName = capitalize(name);
const hour = new Date().getHours();
const greetMessage = hour >= 6 && hour < 12 ? "Good morning" : "Hello";
return `${greetMessage} ${capitalizedName}!`;
};
greeter.test.js
describe("#testing greet function with babel-plugin-rewire", () => {
// capitalizeをモック化
beforeAll(() => {
greeter.__set__({
capitalize: jest.fn().mockImplementation(() => "Foo"),
});
});
//前後のテストに影響が出ないようにリセット
afterAll(() => {
greeter.__ResetDependency__("capitalize");
});
// プライベート関数のモック化の確認
it("return `Hello Foo`", () => {
expect(greet("foo")).toBe("Hello Foo!");
});
});
// プライベート関数のテスト
describe("#capitalize", () => {
const capitalize = greeter.__get__("capitalize");
it("return string which the first char is capitalized", () => {
expect(capitalize("hoge")).toBe("Hoge");
});
});
モジュールをインポートした変数に対して、__get__
を使って、指定した関数を取得することができます。
const capitalize = greeter.__get__("capitalize");
モジュールをインポートした変数に対して、__set__
を使って、指定した関数をモック化することができます。下記のコードのでは、capitalize関数をモック化し、文字列のFooを返すように設定しております。
greeter.__set__({
capitalize: jest.fn().mockImplementation(() => "Foo"),
});
前後のテストに影響が出ないようにafterAll()で__ResetDependency__
を使ってリセットしています。
afterAll(() => {
greeter.__ResetDependency__("capitalize");
});