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