在 SSR 中模擬 Next-Auth 以進行 E2E 測試
17 Jul 2025Next.js 是一個支援伺服器端渲染 (SSR) 的框架。在實作中通常採用混合方式—應用程式的某些部分依賴於 SSR 傳遞資料,而其他部分則使用客戶端渲染 (CSR)。然而,目前針對 next-auth
的端到端 (E2E) 測試設定僅涵蓋 CSR 的情境。本文目的為試圖擴展測試的範圍,使其也能支援 SSR,同時具備根據不同條件動態配置的彈性。為了實現這一目標,SSR 和 CSR 都必須能支援模擬身分驗證,否則在測試期間將不得不完全忽略身分驗證。
也就是說,我們的目的是…
- 對 Next.js 專案進行 E2E 測試。
- 支援 SSR 和 CSR 的模擬身分驗證,確保在每個環境中都回應正確資料。
- 根據不同的測試情境啟用動態配置,允許彈性注入客製化的測試資料。
- 明確區分 development 與 production 環境,確保模擬身分驗證不會干擾 production 環境的正常運作。
預期會希望能產出類似 Vitest 或 Jest 的 vi.fn
、vi.mock
或 vi.spyOn
來模擬 getServerSession
的功能,這樣就能在測試期間模擬 getServerSession
的行為,並根據不同的情境回應相應的 session 資料。
關於解法以下是一些提案。
解法 1:使用 next-auth-mock
next-auth-mock
是專為使用 Vitest 或 Jest 進行單元測試設計的工具。它透過在 Node.js 環境中模擬 session object 來運作。然而,由於 E2E 框架在進行測試時是在瀏覽器層級操作,next-auth-mock
無法在此情境中使用。建議參考解法 2 可能會是更適合的方法。
解法 2:使用 CredentialsProvider
模擬身分驗證
用 CredentialsProvider
取代 Google auth 或 Keycloak 機制,並僅在測試環境中使用。注意,使用環境變數來判定是否啟用這個假的 CredentialsProvider
。
非 auth 相關的其他 API 回應也可透過專為測試環境設計的 mockApiProvider
來模擬,從而自動模擬 API 回應。要注意的是,頁面層級的路由如 Playwright 的 page.route
僅適用於 CSR,不能用來模擬 SSR 階段的 API 呼叫。SSR 的 getServerSideProps
的操作是在伺服器端執行,而這些 E2E 框架的測試則是模擬客戶端/瀏覽器端的互動。因此,page.route
無法攔截 SSR 階段的 API 呼叫。 若要在僅限測試的環境中實現 SSR 回應模擬,建議使用環境變數結合專為測試設計的模擬模組,在測試環境中啟用 SSR 模擬,同時保持 production 環境不受影響。
如何根據不同的使用情境調整測試資料,可以考慮以下幾種方式:
- 真實登入(Google auth / Keycloak):使用實際的登入流程進行身分驗證,以模擬真實情境。
- 測試登入(mock credentials):使用模擬憑證,避免在測試中進行真實的身分驗證。
- 手動輸入帳戶憑證:允許在登入過程中手動輸入所需的使用者名稱與密碼。
- 使用 E2E 測試框架自動化登入(跳過 UI):利 E2E 測試框架自動執行登入操作,直接向 authentication API endpoint 發送請求,跳過 UI。
解法 3:透過 MSW 模擬 Session
如果不想透過 CredentialsProvider
模擬登入,可以考慮 (1) 使用 MSW 模擬 session 的 API 呼叫,它會回應一個固定的模擬 session 物件;或是 (2) 在 Node 環境中,直接用模擬物件替代由 getServerSession
回應的 session 物件。透過 MSW 模擬 session 的解法特別適合用於單元測試或整合測試。但要注意的是 MSW 會攔截 HTTP 請求,適用於 CSR,並且由於 session 的解析是在伺服器端進行,而非在客戶端或瀏覽器端完成,因此無法用於 SSR。
解法 4:跳過身分驗證流
如果上述方案均無法實現,可以考慮在測試過程中完全跳過身分驗證流程。幸運的是解法 2 是可行的,不需要跳過身分驗證的步驟,而能進行完整的 E2E 測試。
總結
以下是各種解法的對比表:
解法 | 適用情境 | 優點 | 缺點 |
---|---|---|---|
解法 1:使用 next-auth-mock |
單元測試 | 簡單易用, 快速模擬使用者狀態 | 僅限於單元測試, 不適用於端到端測試(E2E) |
解法 2:使用 CredentialsProvider | 端到端測試(CSR 和 SSR 渲染) | 支援真實的身分驗證模擬, 同時適用於 CSR 和 SSR 渲染場景, 可利用環境變數彈性進行配置 | 需要額外設置, 注入測試資料更加複雜 |
解法 3:使用 MSW 模擬 session | CSR 渲染 | 對 API 回應有高度控制, 適合前端測試 | 無法覆蓋 SSR 渲染, 需要額外的測試環境設置 |
解法 4:跳過身分驗證流程 | 基本功能測試 | 簡單快捷, 無需額外配置 | 無法測試身分驗證行為,` 不支援全面的端到端測試 |
跟預期不同的是,最後並沒有實現類似 Vitest 或 Jest 的 vi.fn
、vi.mock
或 vi.spyOn
的功能來模擬 getServerSession
。這是因為在 SSR 渲染階段,getServerSession
的行為是在伺服器端執行,而 E2E 測試框架通常是在客戶端/瀏覽器端進行操作。因此,無法直接在客戶端模擬伺服器端的行為。
推薦的解決方案是使用 CredentialsProvider
來模擬身分驗證,這樣就可以在 SSR 和 CSR 渲染中都能有效地支援測試。這種方法不僅能夠模擬身分驗證,還能根據不同的環境變數進行動態配置,進而提升測試的彈性。