Let’s into a fresh directory called ‘testing-example’ and type npm init -y
in our terminal.
Run npm install fastify && npm install tap pino-pretty --save-dev
First, we are going to separate our application code from our server code:
app.js:
server.js:
'use strict'
const server = require('./app')({
logger: {
level: 'info',
prettyPrint: true
}
})
server.listen(3000, (err, address) => {
if (err) {
console.log(err)
process.exit(1)
}
})
Fastify comes with built-in support for fake HTTP injection thanks to .
Before introducing any tests, we will use the .inject
method to make a fake request to our route:
app.test.js:
'use strict'
const build = require('./app')
const test = async () => {
const app = build()
const response = await app.inject({
method: 'GET',
url: '/'
})
console.log('status code: ', response.statusCode)
console.log('body: ', response.body)
}
test()
First, our code will run inside an asynchronous function, giving us access to async/await.
Run the test file in your terminal node app.test.js
status code: 200
body: {"hello":"world"}
Now we can replace our console.log
calls with actual tests!
In your package.json
change the “test” script to:
"test": "tap --reporter=list --watch"
app.test.js:
'use strict'
const { test } = require('tap')
const build = require('./app')
test('requests the "/" route', async t => {
const app = build()
method: 'GET',
})
t.equal(response.statusCode, 200, 'returns a status code of 200')
})
Finally, run npm test
in the terminal and see your test results!
The inject
method can do much more than a simple GET request to a URL:
.inject
methods can also be chained by omitting the callback function:
fastify
.inject()
.get('/')
.headers({ foo: 'bar' })
.query({ foo: 'bar' })
.end((err, res) => { // the .end call will trigger the request
console.log(res.payload)
})
or in the promisified version
fastify
.inject({
method: String,
url: String,
query: Object,
payload: Object,
headers: Object,
cookies: Object
})
.then(response => {
// your tests
})
.catch(err => {
// handle error
})
try {
const res = await fastify.inject({ method: String, url: String, payload: Object, headers: Object })
// your tests
} catch (err) {
// handle error
}
Another Example:
app.js
const Fastify = require('fastify')
function buildFastify () {
const fastify = Fastify()
fastify.get('/', function (request, reply) {
reply.send({ hello: 'world' })
})
return fastify
}
module.exports = buildFastify
test.js
Fastify can also be tested after starting the server with fastify.listen()
or after initializing routes and plugins with fastify.ready()
.
Example:
Uses app.js from the previous example.
test-listen.js (testing with Request
)
const tap = require('tap')
const buildFastify = require('./app')
tap.test('GET `/` route', t => {
t.plan(5)
const fastify = buildFastify()
t.teardown(() => fastify.close())
fastify.listen(0, (err) => {
t.error(err)
request({
method: 'GET',
url: 'http://localhost:' + fastify.server.address().port
}, (err, response, body) => {
t.error(err)
t.equal(response.statusCode, 200)
t.equal(response.headers['content-type'], 'application/json; charset=utf-8')
t.same(JSON.parse(body), { hello: 'world' })
})
})
})
test-ready.js (testing with )
const tap = require('tap')
const supertest = require('supertest')
const buildFastify = require('./app')
tap.test('GET `/` route', async (t) => {
const fastify = buildFastify()
t.teardown(() => fastify.close())
await fastify.ready()
const response = await supertest(fastify.server)
.get('/')
.expect(200)
.expect('Content-Type', 'application/json; charset=utf-8')
t.same(response.body, { hello: 'world' })
})
Isolate your test by passing the
{only: true}
optiontest('should ...', {only: true}, t => ...)
Run
tap
usingnpx
> npx tap -O -T --node-arg=--inspect-brk test/<test-file.test.js>
-O
specifies to run tests with theonly
option enabled-T
specifies not to timeout (while you’re debugging)--node-arg=--inspect-brk
will launch the node debugger
- In VS Code, create and launch a
Node.js: Attach
debug configuration. No modification should be necessary.
Now you should be able to step through your test file (and the rest of Fastify
) in your code editor.