How to mock a function while testing Node.js endpoint using chai-http

3.8k Views Asked by At

Endpoint code:

app.post('/api/v1/user', async function (req, res) {
    const user = await createUser(req);
    res.send(user);
});

Integration test: Below test is written to test the endpoint (/api/v1/user). createUser(req); function creates the user into DB. I want to skip creation of user into DB while testing. Could you help me to mock createUser(req); in the below test.

import chai from 'chai';
import chaiHttp from 'chai-http';
chai.use(chaiHttp);
import { app } from '../../server';

describe('Create user tests', function () {
    it('user should be created', function (done) {
        chai.request(app)
            .post('/api/v1/user')
            .set({
                'content-type': 'application/json',
            })
            .send({
                name: 'xxxxx',
                email: '[email protected]',
            })
            .end((err, res) => {
                res.should.have.status(200);

                done();
            });
    });
});

1

There are 1 best solutions below

0
oieduardorabelo On

in case you can replace your runner from mocha to jest, the following solution can work for you:

let fetch = require("node-fetch");

let chai = require("chai");
let chaiHttp = require("chai-http");

let expect = chai.expect;
chai.use(chaiHttp);

let { app } = require("./main");

jest.mock("node-fetch", () => {
  let instance = {
    json: jest.fn(),
  };
  return () => instance;
});

describe("Create user tests", function () {
  it("user should be created", function (done) {
    fetch().json.mockReturnValueOnce("user-created");
    chai
      .request(app)
      .post("/api/v1/user")
      .set({
        "content-type": "application/json",
      })
      .send({
        name: "xxxxx",
        email: "[email protected]",
      })
      .end((err, res) => {
        expect(err).to.be.null;
        expect(res).to.have.status(200);
        expect(res.body.ok).to.equal(true);
        expect(res.body.payload).to.equal("user-created");
        done();
      });
  });

  it("user failed to be created", function (done) {
    fetch().json.mockImplementationOnce(() => {
      throw new Error("test-error");
    });
    chai
      .request(app)
      .post("/api/v1/user")
      .set({
        "content-type": "application/json",
      })
      .send({
        name: "xxxxx",
        email: "[email protected]",
      })
      .end((err, res) => {
        expect(err).to.be.null;
        expect(res).to.have.status(500);
        expect(res.body.ok).to.equal(false);
        expect(res.body.payload).to.equal(undefined);
        expect(res.body.error).to.equal("test-error");
        done();
      });
  });
});

in my example above i used the following server:

let express = require("express");
let fetch = require('node-fetch');


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

async function createUser(params) {
  try {
    let res = await fetch("https://random-data-api.com/api/users/random_user");
    let json = await res.json();
    return { ok: true, payload: json };
  } catch (error) {
    return { ok: false, error: error.message };
  }
}

app.post("/api/v1/user", async function (req, res) {
  let user = await createUser(req);
  if (user.ok) {
    res.status(200).send(user);
  } else {
    res.status(500).send(user);
  }
});

module.exports = { app };

and the following package.json

{
  "dependencies": {
    "chai": "4.3.4",
    "chai-http": "4.3.0",
    "express": "4.17.1",
    "jest": "27.1.0",
    "node-fetch": "2.6.2"
  }
}