Skip to content

Testing 助手

Testing 助手提供了一些函数,帮助你更轻松地测试 Hono 应用。

导入

ts
import { Hono } from 'hono'
import { testClient } from 'hono/testing'

testClient()

testClient() 接收一个 Hono 实例作为第一个参数,返回一个按路由类型定义好的对象,类似于 Hono Client。借助它可以在测试中以类型安全的方式调用各路由,并享受编辑器的自动补全。

关于类型推断的重要说明:

为了让 testClient 正确推断路由类型并提供自动补全,必须直接在 Hono 实例上通过链式调用定义路由

类型推断依赖 .get().post() 等链式调用中流动的类型。如果你按照传统的 “Hello World” 写法(const app = new Hono(); app.get(...))在实例创建后再单独注册路由,testClient 就无法获取这些类型信息,也就无法提供类型安全的客户端能力。

示例:

以下示例可以正常推断类型,因为 .get() 直接链在 new Hono() 上:

ts
// index.ts
const app = new Hono().get('/search', (c) => {
  const query = c.req.query('q')
  return c.json({ query: query, results: ['result1', 'result2'] })
})

export default app
ts
// index.test.ts
import { Hono } from 'hono'
import { testClient } from 'hono/testing'
import { describe, it, expect } from 'vitest' // 或任意测试框架
import app from './app'

describe('Search Endpoint', () => {
  // 基于应用实例创建测试客户端
  const client = testClient(app)

  it('should return search results', async () => {
    // 使用带类型的客户端调用接口
    // 如果路由中定义了查询参数,这里也会获得类型提示
    // 并通过 .$get() 访问
    const res = await client.search.$get({
      query: { q: 'hono' },
    })

    // 断言
    expect(res.status).toBe(200)
    expect(await res.json()).toEqual({
      query: 'hono',
      results: ['result1', 'result2'],
    })
  })
})

如需在测试请求中携带请求头,可将其作为第二个参数传入。该参数也支持 init 属性(类型为 RequestInit),便于设置请求头、方法、请求体等。关于 init 的更多信息,请参考 这里

ts
// index.test.ts
import { Hono } from 'hono'
import { testClient } from 'hono/testing'
import { describe, it, expect } from 'vitest' // 或任意测试框架
import app from './app'

describe('Search Endpoint', () => {
  const client = testClient(app)

  it('should return search results', async () => {
    // 在请求头中附带 token,并设置内容类型
    const token = 'this-is-a-very-clean-token'
    const res = await client.search.$get(
      {
        query: { q: 'hono' },
      },
      {
        headers: {
          Authorization: `Bearer ${token}`,
          'Content-Type': `application/json`,
        },
      }
    )

    expect(res.status).toBe(200)
    expect(await res.json()).toEqual({
      query: 'hono',
      results: ['result1', 'result2'],
    })
  })
})

Released under the MIT License.