Nest.js
では、公式に用意されたテストユーティリティ (@nestjs/testing)
とSupertest
を組み合わせることで、統合テスト(integration test
)を簡単に作成できます。以下は基本的な手順とサンプルコードです。
テスト用モジュールの作成
-
TestingModule
の作成:
テスト用に対象のモジュール(例えばAppModule
)をインポートし、Test.createTestingModule()
を使ってテスト用モジュールを作成します。 -
Nest アプリケーションインスタンスの生成:
コンパイル後、moduleFixture.createNestApplication()
でNest
アプリケーションのインスタンスを作成し、app.init()
を呼び出して初期化します。
エンドポイントのテスト
Supertest
を利用したエンドポイントのテスト
-
HTTP
リクエストの送信:
app.getHttpServer()
を用いて、Supertest
でHTTP
リクエストをシミュレートし、実際のエンドポイントの動作を確認します。 -
レスポンスの検証:
ステータスコードやレスポンスボディを.expect()
メソッドで検証します。 -
サンプルコード
以下は、GET/
エンドポイントに対する統合テストのサンプルコードです。
import { Test, TestingModule } from '@nestjs/testing';
import { INestApplication } from '@nestjs/common';
import * as request from 'supertest';
import { AppModule } from './../src/app.module';
describe('AppController (Integration Test)', () => {
let app: INestApplication;
// テスト実行前にアプリケーションをセットアップ
beforeAll(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = moduleFixture.createNestApplication();
await app.init();
});
// エンドポイントのテスト例
it('/ (GET)', () => {
return request(app.getHttpServer())
.get('/')
.expect(200)
.expect('Hello World!');
});
// テスト終了後にアプリケーションをクローズ
afterAll(async () => {
await app.close();
});
});
ポイント解説
-
TestingModule
の活用:
Test.createTestingModule
を使うことで、実際のアプリケーションのDI
コンテナやミドルウェア、ガードなどを含む状態でテスト環境を再現できます。 -
Supertest
の利用:
Supertest
によって、HTTP
リクエストを模擬し、API
のエンドツーエンド動作を検証可能です。これは、統合テストとして非常に有用です。 -
後処理:
テスト終了後はapp.close()
を呼び出してリソースを解放し、次のテストへの影響を防ぎます。 -
拡張例:
データベースとの連携がある場合は、テスト用のDB
環境を用意したり、モックを利用するなどしてテストを実行します。
e2e
テストコードを作成
-
エンドツーエンド(e2e)テスト:
アプリケーション全体(ルーティング、ミドルウェア、ガード、コントローラー、サービスなど)が実際に動作しているかを検証します。 -
利用するライブラリ:
@nestjs/testing
でアプリケーションのテスト用インスタンスを作成し、HTTP
リクエストのシミュレーションにはSupertest
を使用します。
e2e
テストのセットアップ
通常、e2e
テストはプロジェクト内のe2e
フォルダに配置され、専用のJest
設定(例: jest-e2e.json
)で実行されます。例えば、package.json
のスクリプトに以下のように記述します。
{
"scripts": {
"test:e2e": "jest --config ./test/jest-e2e.json"
}
}
jest-e2e.json のサンプル設定は以下の通りです。
{
"moduleFileExtensions": ["js", "json", "ts"],
"rootDir": "../",
"testRegex": ".e2e-spec.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"coverageDirectory": "./coverage",
"testEnvironment": "node"
}
サンプルコード
以下は、GET/
エンドポイントに対するe2e
テストのサンプルコードです。アプリケーション全体をテスト用モジュールとしてセットアップし、Supertest
を使ってHTTP
リクエストをシミュレートしています。
import { Test, TestingModule } from '@nestjs/testing';
import { INestApplication } from '@nestjs/common';
import * as request from 'supertest';
import { AppModule } from './../src/app.module';
describe('App E2E Test', () => {
let app: INestApplication;
// テスト実行前にアプリケーションを初期化
beforeAll(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = moduleFixture.createNestApplication();
await app.init();
});
// GET / エンドポイントのテスト
it('GET / should return "Hello World!"', () => {
return request(app.getHttpServer())
.get('/')
.expect(200)
.expect('Hello World!');
});
// テスト終了後にアプリケーションをクローズ
afterAll(async () => {
await app.close();
});
});
このようにしてSupertest
とe2e
テストを実装することで、実際のHTTP
リクエストに基づいたエンドポイントの動作検証が可能となり、アプリケーション全体の品質向上に寄与します。
今日は以上です。
ありがとうございました。
よろしくお願いいたします。