如何在Jest中测试Next.js里使用context的iron-session异步函数
解决Next.js工具函数的Jest测试问题
你遇到的是Next.js中getServerSideProps类异步处理器的测试问题,不用重构也能完成测试,当然重构可以让核心逻辑的测试更简洁,下面分两种方案说明:
方案一:不重构直接测试
因为checker()返回的是被ironSessionUtil包装后的异步处理器函数,测试时需要模拟上下文(context),并await函数执行结果。同时可以通过mockironSessionUtil跳过它的包装逻辑,直接测试你的认证逻辑:
测试代码示例
import checker from './your-checker-file-path' import { ironSessionUtil } from './anotherUtil' // Mock ironSessionUtil,让它直接返回传入的处理器函数 jest.mock('./anotherUtil', () => ({ ironSessionUtil: jest.fn(handler => handler) })) describe('checker函数测试', () => { it('当用户存在时,返回包含用户详情的props', async () => { // 模拟带有已登录用户的context const mockContext = { req: { session: { user: { details: { name: '张三', userId: 1001 } } } } } // 获取处理器并执行 const handler = checker() const result = await handler(mockContext) expect(result).toEqual({ props: { details: { name: '张三', userId: 1001 } } }) }) it('当用户不存在时,返回跳转到/welcome的指令', async () => { // 模拟无用户的context const mockContext = { req: { session: {} } } const handler = checker() const result = await handler(mockContext) expect(result).toEqual({ redirect: { destination: '/welcome', permanent: false } }) }) })
方案二:重构提升可测试性
把核心的认证逻辑从ironSessionUtil的调用中抽离成独立函数,这样可以单独测试逻辑本身,不用依赖ironSessionUtil的包装:
重构后的工具文件
import { ironSessionUtil } from './anotherUtil' // 抽离核心认证逻辑,单独导出以便测试 export const authHandler = ({ req }) => { const { user } = req.session if (!user) { return { redirect: { destination: '/welcome', permanent: false } } } return { props: { details: user.details } } } // 原checker函数保持不变 const checker = () => ironSessionUtil(authHandler) export default checker
重构后的测试代码
测试核心认证逻辑
import { authHandler } from './your-checker-file-path' describe('authHandler核心逻辑测试', () => { it('用户存在时返回正确props', () => { const mockContext = { req: { session: { user: { details: { name: '李四' } } } } } const result = authHandler(mockContext) expect(result).toEqual({ props: { details: { name: '李四' } } }) }) it('用户不存在时返回重定向指令', () => { const mockContext = { req: { session: {} } } const result = authHandler(mockContext) expect(result).toEqual({ redirect: { destination: '/welcome', permanent: false } }) }) })
测试checker的包装逻辑
import checker from './your-checker-file-path' import { ironSessionUtil } from './anotherUtil' import { authHandler } from './your-checker-file-path' jest.mock('./anotherUtil') it('checker正确将authHandler传入ironSessionUtil', () => { checker() expect(ironSessionUtil).toHaveBeenCalledWith(authHandler) })
内容的提问来源于stack exchange,提问作者rulix ensoy
相关产品推荐
相关产品推荐

