iT邦幫忙

2022 iThome 鐵人賽

DAY 18
0
Modern Web

Fastify 101系列 第 18

[Fastify] Day18 - Testing

  • 分享至 

  • xImage
  •  

大家好 我是 Yubin

身為一個開發者,寫測試是非常重要的。這篇文章介紹 Fastify 中要如何對 server 進行測試。
如果對 JavaScript Testing 不熟或沒經驗的朋友,可以先參考這篇正體中文的文章:
Javascript-Testing-Best-Practices


撰寫 Fastify 測試的時候,可以自由的選用測試框架。如,jesttapvitest,等。

Jest Setup

本文以 Jest 作為使用的測試框架。

先安裝相應的套件。

npm i -D jest ts-jest @types/jest

新增 jest.config.js

module.exports = {
  preset: 'ts-jest',
  transform: {
    '^.+\\.(t|j)sx?$': 'ts-jest'
  },
  testEnvironment: 'node',
  moduleFileExtensions: ['ts', 'js']
}

為了方便測試,我們先把程式進入點與設定 Server 的部分分離。

把設定 server 的地方,定義在 server.ts,用來啟動伺服器、定義 route 或註冊 Plugin。

server.ts

import fastify, { FastifyInstance } from 'fastify'

const server: FastifyInstance = fastify()

const startServer: (port: number) => FastifyInstance = (port) => {
  const listenAddress = '0.0.0.0'
  const fastifyConfig = {
    port: port,
    host: listenAddress
  }

  server.listen(fastifyConfig)

  server.get('/', (request, reply) => {
    return reply.status(200).send({ message: 'Hello World' })
  })

  return server
}

export { startServer }

讓程式進入點 index.ts 以 import 的方式使用:

index.ts

import { startServer } from './server'

const port = 8888
startServer(port)

接著開一個測試檔案 server.test.ts

import { FastifyInstance } from 'fastify'
import { startServer } from '../server'

describe('Server test', () => {
  let server: FastifyInstance

  beforeAll(async () => {
    server = startServer(8888)
    await server.ready()
  })

  // test cases ...
})

以 Jest 為例,我們在 beforeAll 的地方,透過我們定義好的 startServer(),把伺服器跑起來。

接著假設我要測的東西是,有一個 Request 進來,是一個 GET / 的 Request,則我要拿到 200 的狀態碼。

test('When GET /, then get 200 status code', async () => {
    const response = await server.inject({
      method: 'GET',
      url: '/'
    })
    expect(response.statusCode).toBe(200)
})

.inject()

透過 server.inject(),我們可以製造一個假的 HTTP Request,並將該 Request 送到我們的 Server 中。對 Server 來說這個 Request 是真實存在的,會開始走過 Fastify 的生命週期。

.inject() 透過帶入參數可以設定期望中的 Request。

const response = await server.inject({
  method: String,
  url: String,
  query: Object,
  payload: Object,
  headers: Object,
  cookies: Object
}

要注意的是 .inject() 回應的型態是 Promise,記得要 await 來拿到 Response。

或是用 callback style 的方式:

server.inject({
  method: String,
  url: String,
  query: Object,
  payload: Object,
  headers: Object,
  cookies: Object
}, (error, response) => {
  // your tests
})

自己覺得用 async/await style 的方式會讓測試看起來比較容易閱讀。

上述程式建置好後,修改 package.json 中的 scripts

以 jest 為例。

"test": "jest --verbose --coverage --runInBand",

然後在 terminal 執行 npm run testnpm t 來啟動測試。

https://ithelp.ithome.com.tw/upload/images/20221003/2015114823M8GY6Ke1.jpg

可以看到測試結果及覆蓋率報告。


備註:
Fastify 官網 使用的是 tap 作為測試框架,如果習慣使用 tap 的朋友也可以去參考參考。


寫測試對於開發者來說非常重要,不僅是為了程式品質,更可以提升開發人員的信心。

也可以搭配 TDD 與 CI Pipeline 等流程,不只讓程式品質與可靠度提升,也讓寫程式的人的心情與生活品質提升。


上一篇
[Fastify] Day17 - Validation and Serialization with Typebox
下一篇
[Fastify] Day19 - Database
系列文
Fastify 10130
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言