I'm trying to stub function called on one of my routes in express Router with request from supertest library. I see that function foo is called correctly, unfortunately it is not replaced by stub function I wrote in test. Code is written in ES6 and I'm using babel-register
and babel-polyfill
to make it work.
I run testing script using
./node_modules/mocha/bin/mocha server --timeout 10000 --compilers js:babel-register --require babel-polyfill --recursive
router.js
import {foo} from '../controller';
const router = new Router();
router.route(ROUTE).post(foo);
controller.js
export function foo(req, res) {
res.status(200).send({
ok: 'ok'
});
}
test.js
import request from 'supertest';
import sinon from 'sinon';
import {app} from 'app';
import * as controller from 'controller';
const agent = request.agent(app);
describe('Admin routes tests', () => {
it('Tests login admin route', async () => {
const bar = () => {
console.log('bar');
};
sinon.stub(controller, 'foo', bar);
const req = await agent
.post(ROUTE)
.set('Accept', 'application/json');
console.log(stub.calledOnce); // false
});
});
Any help would be much appreciated.
Here is the solution:
app.js
:
import express from "express";
import * as controller from "./controller";
const app = express();
app.post("/foo", controller.foo);
export { app };
controller.js
:
export function foo(req, res) {
res.status(200).send({ ok: "ok" });
}
test.js
:
import request from "supertest";
import sinon from "sinon";
import * as controller from "./controller";
import { expect } from "chai";
describe("Admin routes tests", () => {
it("Tests login admin route", (done) => {
const bar = () => {
console.log("bar");
};
const fooStub = sinon.stub(controller, "foo").callsFake(bar);
const { app } = require("./app");
const agent = request.agent(app);
agent
.post("/foo")
.set("Accept", "application/json")
.timeout(1000)
.end((err, res) => {
sinon.assert.calledOnce(fooStub);
expect(res).to.be.undefined;
expect(err).to.be.an.instanceof(Error);
done();
});
});
});
Since you stub foo
controller and its return value is undefined
. For supertest
, there is no response, something like res.send()
, the server will hang until the mocha test timeout and it will cause test failed.
.mocharc.yml
:
recursive: true
require: ts-node/register
timeout: 2000
diff: true
inline-diffs: true
We add .timeout(1000)
for supertest, because we know it will timeout(You stub the foo
controller with bar
). And, make an assertion for this timeout error.
Integration test result with coverage report:
Admin routes tests
bar
✓ Tests login admin route (1341ms)
1 passing (1s)
---------------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
---------------|----------|----------|----------|----------|-------------------|
All files | 95.65 | 100 | 80 | 95.65 | |
app.ts | 100 | 100 | 100 | 100 | |
controller.ts | 50 | 100 | 0 | 50 | 2 |
test.ts | 100 | 100 | 100 | 100 | |
---------------|----------|----------|----------|----------|-------------------|
Source code: https://github.com/mrdulin/mocha-chai-sinon-codelab/tree/master/src/stackoverflow/41600031
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With