ts-rest 的 API 測試手法(1)

分享
ts-rest 的 API 測試手法(1)
Photo by Ferenc Almasi / Unsplash

今天與朋友討論到 ts-rest 撰寫 API test 的時候可以用 Zod 的 safeParse().success 判斷 API Response 的 schema 正不正確。

Sample Code:

const { body, status } = client.users.create({
  body: createUserPayload(),
})

expect(
  userContract.create.responses[201].safeParse(body)
    .success,
).toBe(true)

這樣做確實會減少許多傳統需要手動添加 expect.any(Type)...等等的型別驗證,如果只是單純驗證型別,確實透過 ts-rest 合約搭配的 Zod 的 safeParse 安全型別驗證就能夠減少用 expect.any(Type) 去判斷欄位型別是否正確,尤其欄位多達數以十/百計的時候,更能夠顯著提升測試代碼的可讀性。

const { body, status } = await client.users.create({
  body: createUserPayload(),
})

expect(body).toEqual<typeof body>({
  account: expect.any(String),
  // ...other property type or value validate
})

但依我個人的淺見是:

如果只是單純驗證欄位型別
在 ts-rest 的 api test 其實可以省略這個步驟。

Nest.js為例,如果在有設定 validateResponses: true的情況下,那 API Response 的 Schema 的 Type 如果不符合合約定義,則會自動拋出 Exception。

這樣我認為就不必多做 schema 的驗證(有點多此一舉),測試目標放在資料是否正確以及系統行為是否符合預期才是重點。

ts-rest Module in Nest.js
不過這樣在撰寫測試時,就得要有一個預設認知:
1. 合約定義一定是對的
2. API 實作一定會照合約走
這些細節一定要和團隊溝通過後再選擇合適的做法哦~

以下是我個人常用的測試手法

const payload = createUserPayload()
const { body, status } = await client.users.create({
    body: payload
})

// 以 status 驗證是否成功
if (status !== 201) throw new Error()
// 可以省略 schema validate (if validateResponses: true enabled)

// 以下幾種測試策略,可以用來提升"確認對此功能是否完成的信心度"、KPI 是否達標(X
// 驗證回應資料:API return 的欄位值是不是正確的
expect(body.account).toBe(p.account)

// 驗證系統行為:發個 GET API 測看看資料有沒有真的能從資料庫撈出來了
const { body: getUsersBody, status: getUsersStatus } =
  await client.users.getAll()
expect(body.find(i => i.account === p.account)).toBeTruthy()
至於第 7 行為何不用 expect(status).toBe(201) 而是選擇 throw Error 呢... 那是因為我的 ide 沒有那麼聰明。
如果合約定義了不同的 status 會出現不同格式的 body,且又要判斷資料欄位是否正確,那麼在第 12 行的 expect(body.account).toBe(p.account) 就會出現 TS2339 Error-沒有屬性 account

Read more

Windows Sandbox 沙箱閃退顯示連線已中斷解決方法

Windows Sandbox 沙箱閃退顯示連線已中斷解決方法

想拿 Windows Sandbox 測試東西,隔離環境用完就丟最省事。結果一打開沙箱就直接跳「與 Windows 沙盒環境的連線已中斷。是否要重新連線?」,訊息一出來就閃退,連畫面都還沒進去。 翻到 Eleven Forum 這串,有大神直接講解怎麼解決:把 vGPU 共用關掉。 Just had this issue after using Sandbox for years. My fix, as found in an Arabic YouTube video, is to use gpedit.msc and change the Computer Configuration -> Administrative

By GXiang
關於 Firefox 複製網址列連結貼上文本編輯器沒有網頁 Title 的解決方法

關於 Firefox 複製網址列連結貼上文本編輯器沒有網頁 Title 的解決方法

最近從 Edge 換回 Firefox,用沒幾天就被一個小地方卡住。 在 Edge 上,網址列複製網址、到 AFFiNE 筆記裡貼上,出來的是一條帶網頁標題的超連結,標題直接寫在筆記裡,之後回頭看一眼就知道那是什麼。Firefox 沒有這個行為,貼上去就是一長串網址: 筆記一多,這些網址就是一坨要一條條點開才知道是什麼的東西,關鍵字也搜不到。 先去看官方有沒有打算做。Mozilla Connect 上有這則提案:When copy / pasting URL include Meta Title of the ... - Mozilla Connect,截至寫這篇為止沒看到後續進度。 那就找插件。試了兩個: URL2Clipboard 功能最接近我要的,而且它有個細節做得很好:Ctrl + V 貼出來是帶超連結的標題,Ctrl + Shift + V(貼上為純文字)則只有標題文字,

By GXiang
UV python 操作筆記

UV python 操作筆記

前陣子看到了 uv 這個 python 套件、專案管理器,使用了之後發現簡直快、輕便又好上手,下方是我常使用的指令集 (持續更新中): 查看 python 版本清單 uv python list 💡已安裝的旁邊會顯示 python 安裝目錄位址 安裝 python 版本 # latest uv python install # specific version uv python install <version number> 初始化 uv 專案資料夾。 uv init <project name> 💡新專案預設會自動產生 git repository、.python-version、pyproject.

By GXiang
把 MixerBox 歌單匯入到 Spotify

把 MixerBox 歌單匯入到 Spotify

本文由 個人medium文章 同步 筆者最近從 MixerBox 跳槽到 Spotify,但因為 Spotify 推薦的歌單不符合我的口味,又想把 MixerBox 歌單直接無痛移轉到 Spotify,網路上爬文許久,雖然有看到 Jerry 大大分享的這篇文章,但似乎已經沒辦法使用,既然沒有現成的解決方案,那我們就只好動動自己的小腦袋了🧠 貼心體醒:接下來的內容並不會要求撰寫/查看任何程式🙂 使用工具:瀏覽器, Visual Studio Code 筆者在目前看到的平台歌單轉移工具 TuneMyMusic 中,我發現了一個可能性,在第一步選擇歌曲來源時,有一個選項叫做「任意文本」。 點了之後才發現,原來可以利用歌名加上換行分隔作為清單進行匯入!那事情就簡單多了,我們只要能拿到自己播放清單中的歌曲文字列表就可以直接匯入。 接下來我們來到 MixerBox Web 版頁面,點擊「我的音樂庫」,可以看到自己的歌單。 點擊你想要的歌單後,所有歌曲都會呈現在頁面上。 那麼接下來的問題是:

By GXiang