目次
確認環境
Env | Ver |
---|---|
Node.js | 12.18.3 |
Jest | 26.4.2 |
やりたいこと
以下の実装のときに、parentFunc()
を呼んだ時にchildFunc()
が呼ばれることをテストしたい
function parentFunc() {
console.log('called parentFunc');
childFunc('XXXX');
}
function childFunc(param) {
console.log(`called childFunc ${param}`);
}
各ケース紹介
Case1 そもそも構文がおかしい
テストするためには関数をexportする必要あるが、愚直過ぎて構文的に実行不能になるケース
exports.parentFunc = () => {
console.log('called parentFunc');
// childFuncは別モジュールなので呼べない
childFunc('XXXX');
};
exports.childFunc = (param) => {
console.log(`called childFunc ${param}`);
};
Case2 スコープ違いでテストが失敗する
この実装を実行すると期待通り動作するので、一見すると大丈夫そうに見える
function parentFunc() {
console.log('called parentFunc');
childFunc('XXXX');
}
function childFunc(param) {
console.log(`called childFunc ${param}`);
}
module.exports = { parentFunc, childFunc };
しかしこのテストを流すと失敗する
これはparentFunc()
が呼び出すchildFunc()
が下記case2
の中にないため
parentFunc()
のスコープ内にchildFunc()
がいないことが原因
const case2 = require('./case2');
// こうするとjest.spyOn()の第一引数を満たせないので落ちる
// const { parentFunc, childFunc } = require('./case2');
describe('inside call test', function () {
it('parentFunc', function () {
const spy = jest.spyOn(case2, 'parentFunc');
case2.parentFunc();
expect(spy).toHaveBeenCalled();
});
it('childFunc', function () {
const spy = jest.spyOn(case2, 'childFunc');
case2.parentFunc();
// childFuncはcase2に属していないため呼ばれない
expect(spy).toHaveBeenCalled();
});
});
Case3 テストが成功するケース
const parentFunc = () => {
console.log('called parentFunc');
// parentFunc()の中にchildオブジェクトを注入することで、
// jestがchildFunc()を認識できるようにする
child.childFunc('XXXX');
};
const child = {
childFunc: (param) => {
console.log(`called childFunc ${param}`);
},
};
// childFuncでなく、childオブジェクトをexportするのが味噌
module.exports = { parentFunc, child };
const case3 = require('./case3');
describe('inside call test', function () {
it('parentFunc', function () {
const spy = jest.spyOn(case3, 'parentFunc');
case3.parentFunc();
expect(spy).toHaveBeenCalled();
});
it('childFunc', function () {
// 注入している側のオブジェクトを参照する
const spy = jest.spyOn(case3.child, 'childFunc');
case3.parentFunc();
// child.childFuncはcase3に属しているため呼ばれる
expect(spy).toHaveBeenCalled();
});
});