Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(testing): add plugin testing guide #4849

Merged
merged 3 commits into from
Jul 1, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
149 changes: 147 additions & 2 deletions docs/Guides/Testing.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
<h1 align="center">Fastify</h1>
<h1 style="text-align: center;">Fastify</h1>

## Testing
# 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 [Tap](https://www.npmjs.com/package/tap), which is used in
the examples below).

**Table of contents**
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed as the site will generate a ToC from the markdown headers: https://fastify.dev/docs/latest/Guides/Testing

- [Testing](#testing)
- [Application](#application)
- [Plugins](#plugins)

## Application

Let's `cd` into a fresh directory called 'testing-example' and type `npm init
-y` in our terminal.

Expand Down Expand Up @@ -345,3 +353,140 @@ test('should ...', {only: true}, t => ...)

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 && npm i tap -D`

To use ESM (`import` statements)
Copy link
Member

@Fdawgs Fdawgs Jun 25, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All other examples in our documentation use CommonJS, can you please do the same for this example?


**package.json**:
```json
"type": "module"
```

**plugin/myFirstPlugin.js**:

```js
import fP from "fastify-plugin"

async function myPlugin(fastify, options) {
fastify.decorateRequest("helloRequest", "Hello World")
fastify.decorate("helloInstance", "Hello Fastify Instance")
}

export default fP(myPlugin)
```

A basic example of a Plugin. See [Plugin Guide](./Plugins-Guide.md)

**test/myFirstPlugin.test.js**:

```js
import Fastify from "fastify";
import tap from "tap";
import myPlugin from "../plugin/myFirstPlugin.js";

tap.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": "tap --reporter=list --watch"`

Create the tap test for the endpoint.

**test/myFirstPlugin.test.js**:

```js
import Fastify from "fastify";
import tap from "tap";
import myPlugin from "../plugin/myFirstPlugin.js";

tap.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.equal(fastifyResponse.statusCode, 200)
t.same(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
import Fastify from "fastify";
import tap from "tap";
import myPlugin from "../plugin/myFirstPlugin.js";

tap.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.not(request.helloRequest, null)
t.ok(request.helloRequest, "Hello World")
t.ok(fastify.helloInstance, "Hello Fastify Instance")
return ({ message: request.helloRequest })
})

const fastifyResponse = await fastify.inject({
method: "GET",
url: "/"
})
t.equal(fastifyResponse.statusCode, 200)
t.same(JSON.parse(fastifyResponse.body), { message: "Hello World" })
})
```
4 changes: 3 additions & 1 deletion docs/Guides/Write-Plugin.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<h1 align="center">Fastify</h1>
<h1 style="text-align: center;">Fastify</h1>

# How to write a good plugin
First, thank you for deciding to write a plugin for Fastify. Fastify is a
Expand Down Expand Up @@ -63,6 +63,8 @@ among different versions of its dependencies.
We do not enforce any testing library. We use [`tap`](https://www.node-tap.org/)
since it offers out-of-the-box parallel testing and code coverage, but it is up
to you to choose your library of preference.
We highly recommend you read the [Plugin Testing](./Testing.md#plugins) to
learn about how to test your plugins.

## Code Linter
It is not mandatory, but we highly recommend you use a code linter in your
Expand Down