JestからPostgresを操作する方法

特定のセットアップデータに依存するテストを実行したい場合、テストランナーから直接データベースを操作する構成が手軽です。

JestなどJavascriptプロジェクトでは、node-postgres を利用できます。
node-postgresはnpm install --save-dev pgでインストールできます。

node-postgresのリファレンスに沿って、DBに接続しSQLを発行します。

Jest用ボイラープレート

JestのbeforeAll(), AfterALl()を利用して、接続・解放を行うコード例は以下のとおりです。
テストデータを一時的に投入するケースを想定して、TRUNCATEを追加してあります。

const { Client } = require('pg');

let client;

beforeAll(async () => {
	client = new Client({
		host: 'localhost',
		user: 'postgres',
		password: 'dbpassword',
		database: 'some_db'
	});
	await client.connect();
	await client.query('TRUNCATE some_table');
});

afterAll(async () => {
	await client.query('TRUNCATE some_table');
	await client.end();
});

DBのリクエストは非同期であるため、async/awaitを適切に記述する必要があります。

jestのbeforeAll()は非同期コードの動作が不安定で、実行時間の長いコードを詰め込むとタイムアウトのエラーが起きやすくなります。
Asynchronous beforeEach / beforeAll? #1256に議論がありますが、再現性がなく決定打なきまま打ち切られています。

beforeAll()では接続処理程度にとどめ、データ追加のクエリは、beforeEach()に分割すると多少安定するようです。
また、各テストケース内でも実行はできるのですが、INSERTが反映されないケースを確認しており、これは切り分けが難しいコードになりがちです。更新処理についてはbeforeEach()に集約した方が安全です。

用途

サーバーサイドnodeのプロジェクトに限らず、フロントエンドのプロジェクトであってもSQLを直接操作できます。

テストケースはクライアント側で制御するため、クライアントのテストコードから直接DB操作した方が対応が明確になるような場合に便利です。

データセットアップのほか、クライアント投稿後のDBデータをSELECTしてDBデータを検証することも可能です。

中馬崇尋
Chuma Takahiro