1 | <h1 align="center">Fastify</h1>
|
2 |
|
3 | ## Testing
|
4 | Testing is one of the most important parts of developing an application. Fastify is very flexible when it comes to testing and is compatible with most testing frameworks (such as [Tap](https://www.npmjs.com/package/tap), which is used in the examples below).
|
5 |
|
6 | <a name="inject"></a>
|
7 | ### Testing with http injection
|
8 | Fastify comes with built-in support for fake http injection thanks to [`light-my-request`](https://github.com/fastify/light-my-request).
|
9 |
|
10 | To inject a fake http request, use the `inject` method:
|
11 | ```js
|
12 | fastify.inject({
|
13 | method: String,
|
14 | url: String,
|
15 | query: Object,
|
16 | payload: Object,
|
17 | headers: Object
|
18 | }, (error, response) => {
|
19 | // your tests
|
20 | })
|
21 | ```
|
22 |
|
23 | or in the promisified version
|
24 |
|
25 | ```js
|
26 | fastify
|
27 | .inject({
|
28 | method: String,
|
29 | url: String,
|
30 | query: Object,
|
31 | payload: Object,
|
32 | headers: Object
|
33 | })
|
34 | .then(response => {
|
35 | // your tests
|
36 | })
|
37 | .catch(err => {
|
38 | // handle error
|
39 | })
|
40 | ```
|
41 |
|
42 | Async await is supported as well!
|
43 | ```js
|
44 | try {
|
45 | const res = await fastify.inject({ method: String, url: String, payload: Object, headers: Object })
|
46 | // your tests
|
47 | } catch (err) {
|
48 | // handle error
|
49 | }
|
50 | ```
|
51 |
|
52 | #### Example:
|
53 |
|
54 | **app.js**
|
55 | ```js
|
56 | const Fastify = require('fastify')
|
57 |
|
58 | function buildFastify () {
|
59 | const fastify = Fastify()
|
60 |
|
61 | fastify.get('/', function (request, reply) {
|
62 | reply.send({ hello: 'world' })
|
63 | })
|
64 |
|
65 | return fastify
|
66 | }
|
67 |
|
68 | module.exports = buildFastify
|
69 | ```
|
70 |
|
71 | **test.js**
|
72 | ```js
|
73 | const tap = require('tap')
|
74 | const buildFastify = require('./app')
|
75 |
|
76 | tap.test('GET `/` route', t => {
|
77 | t.plan(4)
|
78 |
|
79 | const fastify = buildFastify()
|
80 |
|
81 | // At the end of your tests it is highly recommended to call `.close()`
|
82 | // to ensure that all connections to external services get closed.
|
83 | t.tearDown(() => fastify.close())
|
84 |
|
85 | fastify.inject({
|
86 | method: 'GET',
|
87 | url: '/'
|
88 | }, (err, response) => {
|
89 | t.error(err)
|
90 | t.strictEqual(response.statusCode, 200)
|
91 | t.strictEqual(response.headers['content-type'], 'application/json; charset=utf-8')
|
92 | t.deepEqual(JSON.parse(response.payload), { hello: 'world' })
|
93 | })
|
94 | })
|
95 | ```
|
96 |
|
97 | ### Testing with a running server
|
98 | Fastify can also be tested after starting the server with `fastify.listen()` or after initializing routes and plugins with `fastify.ready()`.
|
99 |
|
100 | #### Example:
|
101 |
|
102 | Uses **app.js** from the previous example.
|
103 |
|
104 | **test-listen.js** (testing with [`Request`](https://www.npmjs.com/package/request))
|
105 | ```js
|
106 | const tap = require('tap')
|
107 | const request = require('request')
|
108 | const buildFastify = require('./app')
|
109 |
|
110 | tap.test('GET `/` route', t => {
|
111 | t.plan(5)
|
112 |
|
113 | const fastify = buildFastify()
|
114 |
|
115 | t.tearDown(() => fastify.close())
|
116 |
|
117 | fastify.listen(0, (err) => {
|
118 | t.error(err)
|
119 |
|
120 | request({
|
121 | method: 'GET',
|
122 | url: 'http://localhost:' + fastify.server.address().port
|
123 | }, (err, response, body) => {
|
124 | t.error(err)
|
125 | t.strictEqual(response.statusCode, 200)
|
126 | t.strictEqual(response.headers['content-type'], 'application/json; charset=utf-8')
|
127 | t.deepEqual(JSON.parse(body), { hello: 'world' })
|
128 | })
|
129 | })
|
130 | })
|
131 | ```
|
132 |
|
133 | **test-ready.js** (testing with [`SuperTest`](https://www.npmjs.com/package/supertest))
|
134 | ```js
|
135 | const tap = require('tap')
|
136 | const supertest = require('supertest')
|
137 | const buildFastify = require('./app')
|
138 |
|
139 | tap.test('GET `/` route', async (t) => {
|
140 | const fastify = buildFastify()
|
141 |
|
142 | t.tearDown(() => fastify.close())
|
143 |
|
144 | await fastify.ready()
|
145 |
|
146 | const response = await supertest(fastify.server)
|
147 | .get('/')
|
148 | .expect(200)
|
149 | .expect('Content-Type', 'application/json; charset=utf-8')
|
150 | t.deepEqual(response.body, { hello: 'world' })
|
151 | })
|
152 | ```
|
153 |
|
154 | ### How to inspect tap tests
|
155 | 1. Isolate your test by passing the `{only: true}` option
|
156 | ```javascript
|
157 | test('should ...', {only: true}, t => ...)
|
158 | ```
|
159 | 2. Run `tap` using `npx`
|
160 | ```bash
|
161 | > npx tap -O -T --node-arg=--inspect-brk test/<test-file.test.js>
|
162 | ```
|
163 | - `-O` specifies to run tests with the `only` option enabled
|
164 | - `-T` specifies not to timeout (while you're debugging)
|
165 | - `--node-arg=--inspect-brk` will launch the node debugger
|
166 | 3. In VS Code, create and launch a `Node.js: Attach` debug configuration. No modification should be necessary.
|
167 |
|
168 | Now you should be able to step through your test file (and the rest of `fastify`) in your code editor.
|