Setup Express API Test with Mocha and Chai using Typescript
Tags: express, testing, mocha, chai
Published: 2019-07-06 02:31:28

---
title: Setup Express API Test with Mocha and Chai using Typescript
published: true
description: In this post, I will walk through the easy process of setting up the test in Express API with Mocha and Chai using Typescript
tags: Express, Testing, Mocha, Chai
---

Today, I'll be explaining how we can easily set up the testing environment
for the development of an Express API app. In this setup, we will be using Mocha and Chai with Typescript.

So, Let's get started.

First things first. Let's get our basic project setup. We will be using NPM here, but you can use Yarn as well (if you prefer it).

```sh
$ npm init -y
```

This should create a `package.json` file in your current working directory. Next, we install `express, body-parser, and mongoose` for creating a meaningful API using the following command.

```sh
npm i -S express body-parser mongoose
```
Now let's install all the dependencies only we care about (devDependencies).

```sh
npm i -D typescript chai mocha nodemon ts-node supertest​
```
Let's install types for all our dependencies as well. Anyway, How good is typescript without types?

```sh
​​​​​​​npm i -D @types/node @types/mocha @types/express @types/chai @types/supertest @types/mongoose
```
##Setup Typescript
Now let's setup typescript. Just create `​tsconfig.json` file at the root directory and copy the following config.

```javascript
{
    "compilerOptions": {
        "target": "es2017",
        "module": "commonjs",
        "outDir": "dist",
        "sourceMap": true
    },
    "include": [
        "src/**/*.ts"
    ],
    "exclude": [
        "node_modules",
        "test/**/*.ts"
    ]
}
```

##Test script
In our package.json file let's add a script test-dev to run it continuously every time we make any changes in our codebase. Simply put the following script in the scripts section of `package.json`.

```bash
"test-dev": "nodemon --watch . --ext ts --exec \"mocha -r ts-node/register test/**/*.test.ts\""
```
What this does is ask nodemon to watch all of the folders and run Mocha if it finds any file changes.

Now, let's create a test directory in the root directory and create `index.test.ts` inside it, then add the following scripts.

```typescript
import {expect} from 'chai';
describe("Index Test", () => {
    it('should always pass', function () {
        expect(true).to.equal(true);
    });
});
```

Next, execute `npm run test-dev` to start the test. You should see one test suite passing. Congratulation, you have successfully created your test.

Now, let's add a couple of tests first to test our express app.

```typescript
it('should POST /api/todo v2', async function () {
    const res = await request(app)
        .post('/api/todo').send({todo: "first todo"});
    expect(res.status).to.equal(200);
    expect(res.body).not.to.be.empty;
    expect(res.body.data).not.to.be.empty;
    expect(res.body.data).to.be.an("object");
    expect(res.body.error).to.be.empty;
});
it('should GET /api/todo', async function () {
    const res = await request(app).get('/api/todo');
    expect(res.status).to.equal(200);
    expect(res.body).not.to.be.empty;
    expect(res.body.data).not.to.be.empty;
    expect(res.body.data).to.be.an("array");
    expect(res.body.error).to.be.empty;
});
```
Curious where `request` and `app` comes from? Import them like this.

```typescript
import app from '../src/app';
import {agent as request} from 'supertest';
```

These couple of tests are testing `GET` and `POST` for route `/api/todo`. We know we haven't created express yet, which we will create next. If you have tests running you should see a big error complaining about everything. We aim to fix those error by the end of this post.

##Setup Express App
We create `index.ts` file inside `src` folder and add the following scripts.

```typescript
import * as express from 'express';
import {Todo} from "./models";
import * as mongoose from 'mongoose';
import {json} from 'body-parser';

const app = express();
app.use(json());

if (mongoose.connection.readyState === 0) {
    mongoose.connect('mongodb://localhost:32768/test')
        .then(() => console.log('Db connected...'))
        .catch(e => console.log("Db connection error", e));
}
app.get('/api/todo', async (req, res) => {
    try {
        const todos = await Todo.find({});
        res.status(200).json({error: null, data: todos});
    } catch (e) {
        res.status(500).json({error: e.message, data: null});
    }
});
app.post('/api/todo', async (req, res) => {
    try {
        const todo = await new Todo({todo: req.body.todo}).save();
        res.status(200).json({error: null, data: todo});
    } catch (e) {
        res.status(500).json({error: e.message, todo: null});
    }
});
export default app;
```

It might look huge file to copy, but essentially all this is doing is creating an express with a single route `/api/todo` for `GET` and `POST` method to create a todo (POST) and return all of the todos (GET).

If you are curious where the Todo comes from, it is a mongoose model create in Todo.ts with following contents.

```typescript
import * as mongoose from 'mongoose';
const Todo = mongoose.model('todo',
    new mongoose.Schema({
            todo: String,
            complete: {
                type: Boolean,
                default: false
            }
        }
    )
);
export default Todo;
```

This way, we can follow Test Driven Development (TDD) approach. I've written this post to help others get started quickly, as it took me quite a bit of time to figure this out. Please feel free to correct me if I've mistaken about anything.