question: how to declaratively create `H3Event`'s to test event handlers
juliusmarminge opened this issue · comments
Describe the change
How should one create H3Event's in order to test their event handlers? Assume I just want to run this event handler as a function, without having to create a server and listening to it? I came up with a workaround to use the web-converter and passing it a Request
instead, but that feels a bit "hacky" I think
I'd just want to be able to do something like
eventHandler(new H3Event({ /** some options */}))
but the constructor args are very confusing for this use-case
URLs
No response
Additional information
- Would you be willing to help?
Was just looking for this myself =)
It's very tricky to test h3 without listening to a server.
I did have success with the following:
import { createEvent } from 'h3'
const req = <IncomingMessage>{
method: 'POST',
path: '...',
headers: new Headers(...),
body: {
...
}
}
const res = <ServerResponse>{}
const event = createEvent(req, res)
// Some internal stuff that h3 does, sometimes needed, sometimes not
event._method = req.method
event._path = req.path
event._headers = req.headers
if (req.body) {
event._requestBody = req.body
}
// Run the event logic
await app(...).use(...)(event)
// However now you have to deal with handling the raw response object, which is extortionary annoying
expect(res.status).toBe(200) // will most likely fail
Working with https://github.com/ladjs/supertest make things easier and way more reliable.
An example with Vite:
// some.test.ts
import type { App } from 'h3'
import { createApp, eventHandler, toNodeListener } from 'h3'
import type { SuperTest, Test } from 'supertest'
import supertest from 'supertest'
describe('', () => {
let app: App
let request: SuperTest<Test>
beforeEach(() => {
app = createApp({ debug: false })
request = supertest(toNodeListener(app))
})
it('', async () => {
app.use('/api/test', eventHandler(() => {
return 'hello world'
}))
const result = await request.get('/api/test').send()
expect(result.text).toBe('hello world')
})
})
There are plenty more examples you can look at: https://github.com/unjs/h3/tree/main/test
so that's basically what I had just with the node listener instead of the web handlers
Hi dear @juliusmarminge. With upcoming h3 v2, mockEvent
can be used to easily create a mocked (web API backed) event for testing. we use it internally too.