首頁 > web前端 > 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 專案時,我遇到了一個重大障礙。我需要測試 GraphQL API 的身份驗證,該驗證依賴於 HTTP 標頭中傳遞的 JSON Web 令牌 (JWT)。最初,我努力尋找一種直接的方法來在 Jest 中模擬這些標頭。標準 Jest 設定還不夠,因為它沒有像真實伺服器那樣直接處理 HTTP 請求和回應。

解決方案:發現 SuperTest

經過多次嘗試和錯誤,我遇到了 SuperTest,一個專為 HTTP 斷言設計的函式庫。 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 中模擬 header 的困難導致了 SuperTest 的發現,它大大簡化了過程。透過利用 SuperTest 和 Jest,我能夠有效地測試 GraphQL API 的身份驗證和 CRUD 操作,確保應用程式的安全性和功能。分享這個學習過程突顯了公共學習和社區驅動的問題解決的力量。

以上是使用 Jest 和 SuperTest 測試 GraphQL 應用程式的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板