Samaila Bala I'm a frontend engineer and technical writer.

How to test Strapi endpoints with Mocha and Chai

5 min read 1419

Testing Strapi Applications With Mocha and Chai

Testing is a fundamental building block that is often overlooked when developing applications. It gives the user a measure of assurance as to the quality of the finished product and usually helps uncover errors.

In this tutorial, we’ll go over how to test RESTful APIs built with Strapi, which is an open-source headless JavaScript CMS. It’s used to build customizable API’s quickly and without worrying much about the details of the underlying architecture.

We will use the Mocha testing framework and the Chai assertion library to test the endpoints built on Strapi.

Prerequisites

This tutorial assumes the you have the following:

  • Knowledge of JavaScript
  • Node.js v12.x or greater
  • npm v6.x or greater
  • Knowledge of testing
  • Postman (an API client)

Installation

To get started using Strapi, open your terminal and run the following to install.

npx create-strapi-app strapi-mocha-chai --quickstart

The above command will initialize a Strapi project called strapi-mocha-chai. The --quicktart flag will initialize Strapi with an Sqlite database. If you want to be able to select a database of your choice, omit the flag.

After installation, the app should start automatically. If it doesn’t, run npm develop to start it.

Navigate to http://localhost:1337/ on your browser to view the application. You should see a screen like the one below.

Strapi Sign-Up

Fill the form and submit it. After submitting, it takes you to the dashboard, where you can start creating API endpoints.

We made a custom demo for .
No really. Click here to check it out.

Creating endpoints

We’ll be create a to-do application with the following endpoints.

  • POST /todos — an endpoint to create a new todo
  • GET /todos — an endpoint to get a list of all todos
  • GET /todos/:id — anendpoint to get a single todo
  • PUT /todos/:id — an endpoint to update an existing todo
  • DELETE /todos/:id — an endpoint to delete an existing todo

To create these RESTful API endpoints, we have to create a content type, which is similar to a database definition. Go to “Plugins” on the sidebar and click “Content Types Builder” on the page that opens.

  1. Click “Create new collection type.” You should see a modal like the one below.
    Strapi Collection Type Configuration
  2. Type “Todos” as the the display name and click “Continue”
  3. Another modal will open up. Click “Text” and type the title as the name
  4. Go to “Advanced Settings” and check “Required”
  5. Click “Add another field”
  6. Click “Boolean” and type “completed” in the name field
  7. Go to “Advanced Settings” and click “False” as the default value
  8. Click “Finish” and then “Save”
  9. The Content Type has now been created. Let’s quickly add some sample data to it
  10. Go to “Collection Types” on the sidebar and click “Todos”
  11. Click “Add New Todos” on the page that opens, insert a sample to-do, and save

Finally, let’s create our endpoints.

  1. Click “Roles and Permissions” in the “Plugins” section.
  2. Click “Public and scroll down to “Permissions”
  3. Check the following boxes in the to-do under “Permissions” and save
    • create
    • delete
    • find
    • findone

Finally, open Postman to check whether the endpoints are working as desired. I’ve created docs for the collection. Open it and click “Run in Postman” to test in your Postman client.

Testing

To get started with testing, you must first install the necessary libraries.

Open your terminal and run the code below.

yarn add mocha chai chai-http cross-env

After installation, go to package.json and add a test command to the script section.

"scripts": {
  "develop": "strapi develop",
  "start": "strapi start",
  "build": "strapi build",
  "strapi": "strapi",
  "test": "cross-env NODE_ENV=test mocha --timeout 10000"
}

Mocha is a simple and flexible JavaScript testing framework for Node.js applications. It allows for serial and asynchronous testing. Chai is a BDD/TDD assertion library that can be paired with Mocha. The chai-http plugin allows you to create integration tests and test HTTP, APIs, or external services.

To separate your test environment from the dev environment, use cross-env to set the NODE_ENV to test before you run any test.

Setting up the test environment

Before you begin writing tests, you need to create a separate database config for your tests so it doesn’t interfere with the development database.

Open your terminal in the root directory and run the following.

cd config
mkdir env && cd env
mkdir test && cd test
touch database.json

This creates a database.json in the following path ./config/env/test/. Open the database.json in your editor and paste the following.

{
  "defaultConnection": "default",
  "connections": {
    "default": {
      "connector": "bookshelf",
      "settings": {
        "client": "sqlite",
        "filename": ".tmp/test.db"
      },
      "options": {
        "useNullAsDefault": true,
        "pool": {
          "min": 0,
          "max": 15
        }
      }
    }
  }
}

The "filename": ".tmp/test.db" property is the location of the temporary database, which will regenerate each time you run the tests. You also need to create an instance of the Strapi server before you run the test.

Paste the following in your terminal.

mkdir tests
cd tests and mkdir helpers
touch strapi.js

This creates a strapi.js file in the following path /tests/helpers/. Open the file and paste the following.

const Strapi = require('strapi');
const http = require('http');
let instance;
async function setupStrapi() {
  if (!instance) {
    /** the following code in copied from `./node_modules/strapi/lib/Strapi.js` */
    await Strapi().load();
    instance = strapi; // strapi is global now
    await instance.app
      .use(instance.router.routes()) // populate KOA routes
      .use(instance.router.allowedMethods()); // populate KOA methods
    instance.server = http.createServer(instance.app.callback());
  }
  return instance;
}
module.exports = { setupStrapi };

Testing the Strapi instance

We’ll create our tests in the test directory. Navigate to /tests/ and create a file called app.test.js. Open the file and paste the code below.

const fs = require('fs');
const { setupStrapi } = require('./helpers/strapi');
const chai = require('chai');
const expect = chai.expect;

before((done) => {
  setupStrapi();
  done();
});

after((done) => {
  const dbSettings = strapi.config.get('database.connections.default.settings');
  if (dbSettings && dbSettings.filename) {
    const tmpDbFile = `${__dirname}/../${dbSettings.filename}`;
    if (fs.existsSync(tmpDbFile)) {
      fs.unlinkSync(tmpDbFile);
    }
  }
  done();
});

it('strapi is defined', (done) => {
  expect(strapi).to.exist;
  done()
});

The above tests the Strapi instance to see if it is initialized. The Strapi instance was initialized in the before hook, which runs before any test runs.

After testing, delete the test database in the after hook so that a fresh database can be generated before you run the tests again.

Testing the endpoints

To begin testing the endpoints, create a file called index.test.js in this path ./tests/todo/ and paste the code below.

const fs = require('fs');
const { setupStrapi } = require('../helpers/strapi');
const chai = require('chai');
const chaiHttp = require('chai-http');
const expect = chai.expect;
chai.use(chaiHttp);

let app;

before(async () => {
  app = await setupStrapi();
});

after((done) => {
  const dbSettings = app.config.get('database.connections.default.settings');
  if (dbSettings && dbSettings.filename) {
    const tmpDbFile = `${__dirname}/../${dbSettings.filename}`;
    if (fs.existsSync(tmpDbFile)) {
      fs.unlinkSync(tmpDbFile);
    }
  }
  done();
});

it('creates a todo item', (done) => {
  chai
    .request(app.server)
    .post('/todos/')
    .send({
      "title": "Sample 2",
      "completed": true
    }).end((error, response) => {
      expect(response).to.have.status(200);
      expect(response).to.have.property('body');
      expect(response.body).to.have.property('title');
      done();
    })
});

it('updates a todo item', (done) => {
  chai
    .request(app.server)
    .put('/todos/1')
    .send({
      "title": "Updated todo",
      "completed": true
    }).end((error, response) => {
      expect(response).to.have.status(200);
      expect(response).to.have.property('body');
      expect(response.body.title).to.equal('Updated todo');
      done();
    })
});

it('gets the list of all todos', (done) => {
  chai
    .request(app.server)
    .get('/todos')
    .end((error, response) => {
      expect(response).to.have.status(200);
      expect(response.body).to.be.an('array');
      done();
    })
});

it('gets a todo item', (done) => {
  chai
    .request(app.server)
    .get('/todos/1')
    .end((error, response) => {
      expect(response).to.have.status(200);
      expect(response.body).to.be.an('object');
      done();
    })
});

it('deletes a todo item', (done) => {
  chai
    .request(app.server)
    .delete('/todos/1')
    .end((error, response) => {
      expect(response).to.have.status(200);
      expect(response.body).to.be.an('object');
      done();
    })
});

As mentioned earlier, you’ll want to set up an instance of the Strapi connection before you carry out the tests and regenerate the test database after each test is done. Then, proceed to create a test for each of the endpoints to be sure they work as expected.

To run the tests, open up terminal and run yarn test. You should get results similar to the screenshot belo.

Conclusion

In this tutorial, we walked through how to test Strapi applications with the Mocha testing framework and the Chai assertion Library.

Testing will always an integral part of the software development lifecycle and you shouldn’t overlook it.

The repository for this tutorial is available on GitHub.

You come here a lot! We hope you enjoy the LogRocket blog. Could you fill out a survey about what you want us to write about?

    Which of these topics are you most interested in?
    ReactVueAngularNew frameworks
    Do you spend a lot of time reproducing errors in your apps?
    YesNo
    Which, if any, do you think would help you reproduce errors more effectively?
    A solution to see exactly what a user did to trigger an errorProactive monitoring which automatically surfaces issuesHaving a support team triage issues more efficiently
    Thanks! Interested to hear how LogRocket can improve your bug fixing processes? Leave your email:

    Are you adding new JS libraries to improve performance or build new features? What if they’re doing the opposite?

    There’s no doubt that frontends are getting more complex. As you add new JavaScript libraries and other dependencies to your app, you’ll need more visibility to ensure your users don’t run into unknown issues.

    LogRocket is a frontend application monitoring solution that lets you replay JavaScript errors as if they happened in your own browser so you can react to bugs more effectively.

    https://logrocket.com/signup/

    LogRocket works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app’s performance, reporting metrics like client CPU load, client memory usage, and more.

    Build confidently — .

    Samaila Bala I'm a frontend engineer and technical writer.

    One Reply to “How to test Strapi endpoints with Mocha and Chai”

    Leave a Reply