nockを使ってHTTPレスポンスをモックする
Blog
Node.jsでHTTP通信を含むコードのテストを書きたい場合があります。 nockは、Node.jsのhttp.request
関数を書き換えて、モックレスポンスを返すライブラリです。
この記事では、Jest + nockを使ってHTTP通信をテストするコードについて記載します。
動作を確認した環境
- Node.js v12.14.0
- jest v24.9.0
- nock v11.7.2
- request v2.88.0
インストール
npm install jest --save-dev
npm install nock --save-dev
# requestモジュールを使うのでrequestモジュールもインストールする
npm install request --save
テスト対象のコード
テスト対象となるコードを作成します。 GitHub.comのREST APIを使って、自分のリポジトリ一覧を取得する fetchRepos
としました。
ファイルは、src
の下にgithub.js
という名前で保存します。
'use strict';
const request = require('request');
const token = 'TOKEN';
const baseUrl = 'https://api.github.com';
const fetchRepos = async () => {
const opts = {
method: 'GET',
url: `${baseUrl}/user/repos`,
headers: {
'Content-Type': 'application/json',
'Authorization': `token ${token}`,
'User-Agent': 'Node-Http-Request'
}
};
return new Promise(function (resolve, reject) {
request(opts, function (error, res, body) {
if (!error && res.statusCode === 200) {
const json = JSON.parse(body);
resolve(json);
} else {
reject(error);
}
});
});
}
module.exports.fetchRepos = fetchRepos;
テストコード
fetchRepos
をテストするテストコードを書きます。 ファイルは、src
の下にgithub.test.js
という名前で保存します。
const nock = require('nock');
const github = require('./github');
const baseUrl = 'https://api.github.com';
describe('Test using nock', () => {
beforeEach(() => {
nock(baseUrl)
.get('/user/repos')
.persist()
.reply(200, {
name: 'chick-p'
});
})
afterEach(() => {
nock.cleanAll();
});
it('should request to github.com', async () => {
try {
const repos = await github.fetchRepos();
expect(repos.name).toEqual('chick-p');
} catch(e) {
console.log(e);
}
});
});
- 8-13行目で、指定したパスに対し、GETしたときのモックレスポンスを作っています。
- レスポンスとして、
{name: 'chick-p'}
が返却されるようにします。 fetchRepos
内で実行されるAPIのパスおよびHTTPメソッドが同じなので、fetchRepos
を実行したときにこのモックレスポンスが呼ばれることになります。- nockでは1回目の呼び出しのみ200が返ってきます。テストコードを通して何度も実行する場合は、
persist()
を設定します。
- レスポンスとして、
- 16行目で、指定したモックレスポンスをすべて解除しています。
テストの実行
テストを実行します。 fetchRepos
でモックに差し替わっているので、テストが合格します。
npx jest src
PASS src/github.test.js
Test using nock
✓ should request to github.com (54ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 3.633s
Ran all test suites matching /src/i