honojs / website

Repository for hono.dev
https://hono.dev
68 stars 208 forks source link

Testing: Add Context section #416

Open JoaquimLey opened 5 days ago

JoaquimLey commented 5 days ago

Also adds an example with custom routing.

Changes available at:

/docs/guides/testing#context
Screenshot 2024-06-29 at 11 11 33

ref: https://github.com/honojs/hono/issues/3026

yusukebe commented 9 hours ago

Hi @JoaquimLey thank you for the PR. I'll comment here.

To set values into your context c.set() for testing, create a custom testing middleware and add it before your test(s) run.

Regarding this, there is not only a case in which we have to set it before each test. If it does not have to initialize something, we can write it without beforeEach.

const app = new Hono<{
  Variables: {
    user: typeof mockUser
  }
}>()

app.use('*', async (c, next) => {
  c.set('user', mockUser)
  await next()
})

const getFriend = vi.fn()

app.get('/user', (c) => {
  const user = c.get('user')
  getFriend(user.id)
  return c.text('/user')
})

describe('Basic', () => {
  it('should return 200 response', async () => {
    const res = await app.request('/user')
    expect(res.status).toBe(200)
    expect(getFriend).toHaveBeenCalledWith(mockUser.id)
  })
})

The problem we have to say is the below case. This test will throw the error Error: Can not add a route since the matcher is already built..

import { Hono } from 'hono'

const adminApp = new Hono()
adminApp.get('/', (c) => c.text('Admin Top'))

const app = new Hono()

beforeEach(() => {
  app.route('/admin', adminApp)
})

describe('Admin route', () => {
  it('should return 200 response', async () => {
    const res = await app.request('/admin')
    expect(res.status).toBe(200)
  })
  it('should return 404 response', async () => {
    const res = await app.request('/admin/foo')
    expect(res.status).toBe(404)
  })
})

To prevent that, we have to write the beforeEach:

let app: Hono

beforeEach(() => {
  app = new Hono()
  app.route('/admin', adminApp)
})

I think what we have to add to the document is this case.