HTTP Server testing library inspired by node-supertest-fetch.
deno add jsr:@deno-libs/superfetchPass a Deno.ServeHandler to makeFetch and it returns a fetch function
bound to a throwaway server hosting that handler.
import { describe, it } from 'jsr:@std/testing/bdd'
import { makeFetch } from 'jsr:@deno-libs/superfetch'
describe('makeFetch', () => {
it('should work with an HTTP handler', async () => {
const handler: Deno.ServeHandler = () => new Response('Hello World')
const fetch = makeFetch(handler)
const res = await fetch('/')
res.expect('Hello World')
})
})expectStatus, expectHeader and expect are chainable. expectBody ends a
chain.
const handler: Deno.ServeHandler = () =>
new Response('teapot', {
status: 418,
headers: { 'Content-Type': 'text/plain' },
})
const fetch = makeFetch(handler)
const res = await fetch('/')
res
.expectStatus(418)
.expectHeader('Content-Type', /text/)
.expectHeader('Coffee-Allowed', null) // assert a header is absent
.expectBody('teapot')expect dispatches on its arguments: a number checks the status, two arguments
check a header, anything else checks the body.
res.expect(418) // same as expectStatus(418)
res.expect('Content-Type', 'text/plain') // same as expectHeader(...)
res.expect('teapot') // same as expectBody('teapot')The body is decoded from the response Content-Type: application/json is
parsed as JSON, text/* as text, anything else as an ArrayBuffer.
const handler: Deno.ServeHandler = () =>
new Response(JSON.stringify({ hello: 'world' }), {
headers: { 'Content-Type': 'application/json' },
})
const res = await makeFetch(handler)('/')
res.expectBody({ hello: 'world' })The first argument is a path, and the second is a regular
RequestInit.
const res = await fetch('/users?limit=10', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'deno' }),
})A single fetch can be reused for as many requests as you like.
const fetch = makeFetch(handler)
for (const path of ['/', '/status', '/header']) {
const res = await fetch(path)
res.expectStatus(200)
}The returned object is a real Response with the assertion helpers and the port
attached.
const res = await fetch('/')
res.expect('Hello World')
console.log(res.status) // 200
console.log(res.headers.get('Content-Type'))
console.log(res.port) // port the handler was served onNote that the body has already been read in order to run the assertions, so
res.json() / res.text() cannot be called again.
makeFetch also accepts a Deno.HttpServer. The server is yours, so superfetch
leaves it running β shut it down when you are done.
const server = Deno.serve({ port: 0, onListen: () => {} }, handler)
const fetch = makeFetch(server)
const res = await fetch('/')
res.expectStatus(200).expectBody('Hello World')
await server.shutdown()