ホームページ > ウェブフロントエンド > jsチュートリアル > Jest と SuperTest を使用した GraphQL アプリケーションのテスト

Jest と SuperTest を使用した GraphQL アプリケーションのテスト

Linda Hamilton
リリース: 2025-01-14 07:31:44
オリジナル
994 人が閲覧しました

Testing a GraphQL Application with Jest and SuperTest

このブログ投稿では、Jest と SuperTest を使用して GraphQL API をテストする際の課題と解決策を検討します。この取り組みは、Jest テストでヘッダー、特にトークンベースの認証をシミュレートする必要があることから始まりました。

課題: Jest でヘッダーをシミュレートする

Woovi チャレンジ用の Todo バックエンド GraphQL プロジェクトを開発しているときに、重大な障害に遭遇しました。 HTTP ヘッダーで渡される JSON Web Token (JWT) に依存する GraphQL API の認証をテストする必要がありました。当初、私は Jest でこれらのヘッダーをシミュレートする簡単な方法を見つけるのに苦労しました。標準の Jest セットアップでは、実際のサーバーと同じ方法で HTTP リクエストとレスポンスを直接処理できないため、十分ではありませんでした。

解決策: SuperTest の発見

何度か試行錯誤した結果、HTTP アサーション用に設計されたライブラリである SuperTest に行き着きました。 SuperTest は、HTTP サーバーを実際のクライアントであるかのようにテストできるようにすることで、Jest の機能を拡張します。この機能により、API の認証に必要な認可トークンを含むヘッダーをシミュレートできるようになりました。

テスト環境のセットアップ

テストに入る前に、環境をセットアップしましょう。

  1. 依存関係をインストールする まず、Jest、SuperTest、および Faker がインストールされていることを確認します。
   npm install --save-dev jest supertest faker
ログイン後にコピー
  1. Jest を構成する jest.config.js ファイルを作成します。
   module.exports = {
     preset: 'ts-jest',
     testEnvironment: 'node',
   };
ログイン後にコピー
  1. テストケースを書く 環境の準備ができたら、テスト ケースを作成できるようになります。

SuperTest を使用してテストを作成する

このシナリオでは SuperTest が状況を一変させました。これを使用して API の CRUD 操作と認証をテストする方法を次に示します。

SuperTest を使用した CRUD 操作のテスト

  1. セットアップと分解 セットアップとティアダウンには Jest の beforeAll フックと afterAll フックを使用します。
   import { connect, disconnectDatabase } from './mongooseConnection';
   import supertest from 'supertest';
   import app from './../index';

   beforeAll(async () => {
     await connect();
   });

   afterAll(async () => {
     await disconnectDatabase();
   });
ログイン後にコピー
  1. 認証とトークンの使用をテストする ユーザーを登録し、トークンを取得するヘルパー関数を作成します。
   import { faker } from '@faker-js/faker';
   import { graphql } from 'graphql';
   import { schema } from '../schema';

   async function authUserTest() {
     const userTest = {
       name: faker.name.firstName(),
       email: faker.internet.email(),
       password: faker.internet.password(),
     };
     const source = `
       mutation {
         register(name: "${userTest.name}", email: "${userTest.email}", password: "${userTest.password}") {
           token
           user {
             name
             email
           }
         }
       }
     `;
     const result = await graphql({ schema, source });
     const data = result.data?.register;
     return data.token;
   }
ログイン後にコピー
  1. タスク CRUD 操作のテスト

    • 新しいタスクを作成する
     it('should create a new task', async () => {
       const todo = {
         task: faker.lorem.words(),
         status: faker.helpers.arrayElement(['pending', 'complete', 'in progress']),
       };
       const query = `
         mutation {
           todo(task: "${todo.task}", status: "${todo.status}") {
             task
             status
           }
         }
       `;
       const { body } = await supertest(app)
         .post('/graphql')
         .send({ query })
         .set('Accept', 'application/json')
         .set('Authorization', `Bearer ${await authUserTest()}`);
       expect(body.data.todo).toMatchObject(todo);
     });
    
    ログイン後にコピー
  • すべてのタスクを取得

     it('should retrieve all tasks', async () => {
       const query = `
         query {
           todos {
             _id
             task
             status
           }
         }
       `;
       const { body } = await supertest(app)
         .post('/graphql')
         .send({ query })
         .set('Accept', 'application/json')
         .set('Authorization', `Bearer ${await authUserTest()}`);
       expect(body.data.todos).toBeInstanceOf(Array);
     });
    
    ログイン後にコピー
  • タスクを更新する

     it('should update a task', async () => {
       const todos = await Todo.find();
       const randomTodo = todos[Math.floor(Math.random() * todos.length)];
       const updatedTask = faker.lorem.words();
       const updatedStatus = faker.helpers.arrayElement(['pending', 'complete', 'in progress']);
       const query = `
         mutation {
           updateTodo(_id: "${randomTodo._id}", task: "${updatedTask}", status: "${updatedStatus}") {
             task
             status
           }
         }
       `;
       const { body } = await supertest(app)
         .post('/graphql')
         .send({ query })
         .set('Accept', 'application/json')
         .set('Authorization', `Bearer ${await authUserTest()}`);
       expect(body.data.updateTodo.task).toBe(updatedTask);
       expect(body.data.updateTodo.status).toBe(updatedStatus);
     });
    
    ログイン後にコピー
  • タスクを削除する

     it('should delete a task', async () => {
       const todos = await Todo.find();
       const randomTodo = todos[Math.floor(Math.random() * todos.length)];
       const query = `
         mutation {
           deleteTodo(_id: "${randomTodo._id}") {
             _id
           }
         }
       `;
       const { body } = await supertest(app)
         .post('/graphql')
         .send({ query })
         .set('Accept', 'application/json')
         .set('Authorization', `Bearer ${await authUserTest()}`);
       expect(body.data.deleteTodo._id).toBe(randomTodo._id);
     });
    
    ログイン後にコピー

テストの実行

Jest を使用してテストを実行します:

npm test
ログイン後にコピー

このコマンドはすべてのテスト ファイルを実行し、結果の詳細なレポートを提供します。

結論

Jest でヘッダーをシミュレートするのは難しいため、プロセスを大幅に簡素化する SuperTest が発見されました。 Jest と SuperTest を併用することで、GraphQL API の認証と CRUD 操作を効果的にテストし、アプリケーションのセキュリティと機能を確保することができました。この学習プロセスを共有することで、公開学習とコミュニティ主導の問題解決の力が強調されます。

以上がJest と SuperTest を使用した GraphQL アプリケーションのテストの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート