概要
- JavaScript テストフレームワークの Jest を使う
- jest.mock を使用してモックを作成し、ユニットテストを実行する
npm init で開発用ディレクトリを用意
$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.
See `npm help json` for definitive documentation on these fields
and exactly what they do.
Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.
Press ^C at any time to quit.
package name: (hello)
version: (1.0.0)
description:
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)
About to write to /Users/me/hello/package.json:
{
"name": "hello",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
Is this OK? (yes)
Jest をインストール
$ npm install --save-dev jest
> fsevents@1.2.8 install /Users/me/hello/node_modules/fsevents
> node install
node-pre-gyp WARN Using request for node-pre-gyp https download
[fsevents] Success: "/Users/me/hello/node_modules/fsevents/lib/binding/Release/node-v64-darwin-x64/fse.node" is installed via remote
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN hello@1.0.0 No description
npm WARN hello@1.0.0 No repository field.
+ jest@24.7.1
added 558 packages from 373 contributors and audited 850808 packages in 12.066s
found 0 vulnerabilities
$ cat package.json
{
"name": "hello",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"jest": "^24.7.1"
}
}
package.json の scipts.test の箇所を Jest を実行するように書き換える。
$ cat package.json
{
"name": "hello",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "jest"
},
"author": "",
"license": "ISC",
"devDependencies": {
"jest": "^24.7.1"
}
}
サンプルコードを用意
getrandomint.js
getrandomint.js
// ランダムな値を返す関数
function getRandomInt(max) {
return Math.floor(Math.random() * Math.floor(max));
}
module.exports = getRandomInt;
getrandomint.test.js
getrandomint.test.js
const getRandomInt = require('./getrandomint');
// ランダムな値ではテストできないので
// 指定した値を返すモック関数を作成
jest.mock('./getrandomint');
const getRandomIntMock = jest.fn((max) => {return max;});
getRandomInt.mockImplementation(getRandomIntMock);
// 指定した値が返ってくるかテスト
test('getRandomInt', () => {
expect(getRandomInt(100)).toBe(100);
});
random.js
random.js
// ランダムな値を返すクラス
class Random {
constructor() {
}
getInt(max) {
return Math.floor(Math.random() * Math.floor(max));
}
}
module.exports = Random;
random.test.js
random.test.js
const Random = require('./random');
// ランダムな値ではテストできないので
// 指定した値を返すモッククラスを作成
jest.mock('./random');
const getIntMock = jest.fn((max) => {return max});
Random.mockImplementation(() => {
return {
getInt: getIntMock,
};
});
// 指定した値が返ってくるかテスト
test('Random.getInt', () => {
expect(new Random().getInt(100)).toBe(100);
});
foobar.js
foobar.js
// getRandomInt 関数と Random クラスを使用する
const getRandomInt = require('./getrandomint');
const Random = require('./random');
// ランダムな数を2つ足して返す関数
function foobar(num) {
const a = getRandomInt(num);
const b = new Random().getInt(num);
return a + b;
}
module.exports = foobar;
foobar.test.js
foobar.test.js
// getRandomInt 関数を読み込む
const getRandomInt = require('./getrandomint');
// ランダムな値ではテストできないので
// 指定した値を返すモック関数を作成
jest.mock('./getrandomint');
const getRandomIntMock = jest.fn((max) => {return max;});
getRandomInt.mockImplementation(getRandomIntMock);
// Random クラスを読み込む
const Random = require('./random');
// ランダムな値ではテストできないので
// 指定した値を返すモッククラスを作成
jest.mock('./random');
const getIntMock = jest.fn((max) => {return max});
Random.mockImplementation(() => {
return {
getInt: getIntMock,
};
});
// getRandomInt 関数とRandom クラスを使用している foobar 関数を読み込む
const foobar = require('./foobar');
// 100を指定したら200が返ってくるかテスト
// foobar 関数の内部では getRandomInt 関数と Random クラスのモックが呼び出されている
test('foobar(100)', () => {
expect(foobar(100)).toBe(200);
});
テストを実行する
$ npm test
> hello@1.0.0 test /Users/me/hello
> jest
PASS ./random.test.js
PASS ./getrandomint.test.js
PASS ./foobar.test.js
Test Suites: 3 passed, 3 total
Tests: 3 passed, 3 total
Snapshots: 0 total
Time: 1.64s
Ran all test suites.
今回の環境
macOS Mojave + Node.js v10.15.3 + Jest 24.7.1
$ node --version
v10.15.3
$ ./node_modules/jest/bin/jest.js --version
24.7.1
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.14.4
BuildVersion: 18E226