0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

nockを使ってapiをmockする

Last updated at Posted at 2024-12-17

概要

jestでインテグレーションテストを実装する際に、外部との疎通に関するテストを書くことがあると思います。
そんなときにnockを使って外部のapiをモックするとより簡潔に実装をすることができます。
今回はそんなnockを使ったmockのやり方をいろいろと紹介したいと思います

nockについて

インストール

今回はyarnを使って

$ yarn install -D nock

実践

それでは早速使っていきましょう!
まずは外部と疎通するようなAPIをexpressを使って実装していきます

実装側

今回はテストを実装するためのexpressのAPIとAPIから呼ばれる外部APIの2つを実装していきます

API

/**
 * =========================
 * 今回テストの対象となるエンドポイント
 * =========================
 */
app.get("/api/v1/sample", async (request: Request, response: Response) => { 
  const res = await axios.get("http://localhost:4000/external-api/v1/sample2");

  response.status(200).json({
    message: res.data.message,
  });
}); 

外部API

/**
 * =========================
 * APIから呼ばれるエンドポイント
 * =========================
 */
app.get("/external-api/v1/sample2", (request: Request, response: Response) => { 
  response.status(200).json({
    message: "This endpoint is sample 2",
  });
});

APIの実行結果は下記となります

{
  "message": "This endpoint is sample 2"
}

テストの実装

nockの実装を紹介していきます。
先程の実装のテストとなります

index.test.ts
import request from 'supertest';
import { app } from '..';
import nock from 'nock';

beforeAll(() => {
	nock.cleanAll();
})

describe('/api/v1/sample2', () => {
	it('get message', async () => {
		// ここでnockを使って外部APIをmockする
		const nockApi = nock('http://localhost:4000')
			// コールするエンドポイント
			.get('/external-api/v1/sample2')
			// モックしたレスポンスの内容
			.reply(200, { message: 'mocked end point' });
		const response = await request(app).get('/api/v1/sample');

		// mockしたエンドポイントが呼ばれたか確認できる
		expect(nockApi.isDone()).toBe(true);
		// ステータスコードの確認
		expect(response.status).toBe(200);
		expect(response.body).toEqual({ message: 'mocked end point' });
	});
})

nockでできること

基本的な使い方は先ほど紹介したい通りですが、ここからもう少し細かくnockを使ってできることを紹介していきます

パラメーターチェック

mockしたapiをコールする際にapi側がパラメータを付けている場合があります。
そんなときはパラーメータを含めたチェックをすることが可能です。
実装側の変更

/**
 * =========================
 * 今回テストの対象となるエンドポイント
 * =========================
 */
app.get("/api/v1/sample", async (request: Request, response: Response) => { 
  // ↓↓↓ ?param=1をリクエストパラメータとしてセット
  const res = await axios.get("http://localhost:4000/api/v1/sample2?param=1");

  response.status(200).json({
    message: res.data.message,
  });
}); 

テスト側の変更

index.test.ts
const nockApi = nock('http://localhost:4000')
	// コールするエンドポイント
	.get('/external-api/v1/sample2')
	// ↓↓↓ 変更:queryメソッドでパラメータチェックをしている ↓↓↓
	// パラメータがあっている場合のみmockされる
	.query({ param: '1' })
	.reply(200, { message: 'mocked end point' });

ハマりどころ

パラメーターチェックを使っていると、想定しているパラメーターではない場合にはうまくmockされません。

そういった場合には下記のようにログを仕込むことによりパラメーターを確認できます。

index.test.ts
const nockApi = nock('http://localhost:4000')
	// コールするエンドポイント
	.get('/external-api/v1/sample2')
	// ↓↓↓ 変更:queryメソッドでパラメータチェックをしている ↓↓↓
	// パラメータがあっている場合のみmockされる
	.query((param) => {
       console.log(param)
       // どんな値でもmockする
       return true
    })
	.reply(200, { message: 'mocked end point' });

一時的にmockされるよう設定し、実際のパラメータにどういう値が渡されているかを確認できます

最後に

今回はnockを使った外部apiのmockについて紹介しました、良かったら参考にしてみてください!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?