How to run two functions in mocha test sequentially - node.js

I have two describe blocks in my mocha-chai test, one for testing a POST API and another for a GET API. There is a dependency like the function for the GET API in turn calls the function for the POST API at first.
However, when I call both the functions one after another, both of them start simultaneously and thus failing.
The code looks like below :
var server;
var mongodb;
before(function (done) {
server = require('../../../app.js'); // same as "node app.js"
done();
})
after(function (done) {
server.close();
})
function this_is_post_call() {
describe('POST call', ()=> {
it('Creating project', (done) => {
chai.request(server)
.post('/create/myproject')
.send()
.end((err, res) => {
expect(res.statusCode).to.equal(200);
done();
});
});
});
}
function this_is_get_call() {
this_is_post_call();
describe('GET call', ()=> {
it('Reading project', (done) => {
chai.request(server)
.get('/read/myproject')
.send()
.end((err, res) => {
expect(res.statusCode).to.equal(200);
done();
});
});
}
this_is_post_call();
this_is_get_call();
Basically when I run this the standalone this_is_post_call() and the one inside this_is_get_call() , gets called simultaneously and it is failing as it tries to create same project twice.
What is the efficient way to call them sequentially so that they don't start until the previous one finishes.
Thanks.

something like this might work (not completely sure about the chai.request part)
var server;
var mongodb;
describe('server', () => {
before(function (done) {
server = require('../../../app.js'); // same as "node app.js"
done();
})
after(function (done) {
server.close();
})
beforeEach(() => {
// find a way to clear the database
// using mongodb variable maybe
})
describe('when you make a post', () => {
var postResult
beforeEach((done) => {
chai.request(server)
.post('/create/myproject')
.send()
.end((err, res) => {
var postResult = res
done();
});
})
})
it('should respond with OK', () => {
expect(postResult.statusCode).to.equal(200);
})
it('should let you make make a get', () => {
chai.request(server)
.get('/read/myproject')
.end((err, res) => {
expect(err).to.be.null;
expect(res.statusCode).to.equal(200);
done();
});
})
})
something like this might work too if you don't have a way to clear the database
var server;
var mongodb;
describe('server', () => {
before(function (done) {
server = require('../../../app.js'); // same as "node app.js"
done();
})
after(function (done) {
server.close();
})
it('should let you post and then get', () => {
var postResult
beforeEach((done) => {
chai.request(server)
.post('/create/myproject')
.send()
.end((err, res) => {
expect(postResult.statusCode).to.equal(200);
chai.request(server) // not sure if this is the correct chai.request format
.get('/read/myproject')
.end((err, res) => {
expect(err).to.be.null;
expect(res.statusCode).to.equal(200);
done();
});
});
})
})
})

Related

Getting “Error: Resolution method is overspecified”? in beforeEach and afterEach

When I use done in beforeEach or afterEach I get this error “Error: Resolution method is overspecified” and the test fails.
But now if remove the done() all my tests pass but the terminal hangs without exiting the test script.
I am using knex.js as a query builder.
Is there a solution to this problem?
beforeEach(async (done) => {
await db.migrate.rollback(migrationConfig);
await db.migrate.latest(migrationConfig);
await db.seed.run(seedConfig);
done();
});
// cleaning db before running tests
afterEach(async (done) => {
await db.migrate.rollback(migrationConfig);
done();
});
describe("POST /user/login", () => {
it("should return a jwt after loging in user", (done) => {
chai
.request(server)
.post("/user/login")
.send({
email: "saaransh#test.com",
password: "test123",
})
.end((err, res) => {
res.should.have.status(200);
res.should.be.json;
res.body.should.have.property("token");
done();
});
});
});
If you are using async handler functions, then you should not give it parameter done. Promise returned by async function will tell Mocha when executing the function is ready.
beforeEach(async () => {
await db.migrate.rollback(migrationConfig);
await db.migrate.latest(migrationConfig);
await db.seed.run(seedConfig);
});
// cleaning db before running tests
afterEach(async () => {
await db.migrate.rollback(migrationConfig);
});

Use ChaiHttp with beforeEach or before method

I have an NodeJS Express application which I want to unit test which uses cookies. So I want to use a beforeEach or before to create the Cookie.
Code which works without any problem (but without the before method):
import * as chai from 'chai';
import { expect } from 'chai'
import chaiHttp = require('chai-http');
import { app } from '../../server';
describe('Relaties', () => {
describe('Ophalen alle relaties met: GET /api/ehrm-klantnr/relatie', () => {
it('should get alle relaties', (done) => {
let agent = chai.request.agent(app)
agent
.put('/api/ehrm-klantnr/medewerker/login')
.send({ email: 'admin#sfgtest.com', wachtwoord: '<secret>' })
.then(function (res) {
expect(res).to.have.cookie('SESSIONID');
// The `agent` now has the sessionid cookie saved, and will send it
// back to the server in the next request:
return agent.get('/api/ehrm-klantnr/relatie')
.set('meta','1')
.then(function (res) {
expect(res).to.have.status(200);
expect(res.body.data[0].vestiging).to.equal('Slib Hoofdkantoor');
done();
});
});
});
});
});
What does not run is this:
import * as chai from 'chai';
import { expect } from 'chai'
import chaiHttp = require('chai-http');
import { app } from '../../server';
describe('Relaties', () => {
let agent = chai.request.agent(app);
describe('First this one', function () {
beforeEach(function () {
console.log('outer describe - beforeEach');
agent
.put('/api/ehrm-klantnr/medewerker/login')
.send({ email: 'admin#sfgtest.com', wachtwoord: '<secret>' })
.then(function (res) {
expect(res).to.have.cookie('SESSIONID');
});
});
});
describe('Ophalen alle relaties met: GET /api/ehrm-klantnr/relatie', () => {
it('should get alle relaties', (done) => {
return agent.get('/api/ehrm-klantnr/relatie')
.set('meta', '1')
.then(function (res) {
expect(res).to.have.status(200);
expect(res.body.data[0].vestiging).to.equal('Slib Hoofdkantoor');
done();
});
});
});
});
It is completely ignoring my before or beforeEach (both methods don't work).
Maybe chai-http does not have before or beforeEach support ?
What am I doing wrong ?
After restructuring.
describe('Relaties', () => {
const agent = chai.request.agent(app);
beforeEach(function (done) {
console.log('outer describe - beforeEach');
agent
.put('/api/ehrm-klantnr/medewerker/login')
.send({ email: 'admin#sfgtest.com', wachtwoord: '<secret>' })
.then(function (res) {
expect(res).to.have.cookie('SESSIONID');
done();
});
});
describe('Ophalen alle relaties met: GET /api/ehrm-klantnr/relatie', () => {
it('should get alle relaties', (done) => {
return agent.get('/api/ehrm-klantnr/relatie')
.set('meta', '1')
.then(function (res) {
expect(res).to.have.status(200);
expect(res).to.be.an('object');
expect(res.body.data).to.be.an('array');
expect(res.body.data[0]).to.be.an('object');
expect(res.body.data[0].id).to.equal(1);
done();
});
});
});
});
I still get errors about the promise.
If this is usefull for someone, this is the final solution:
describe('Relaties', () => {
const agent = chai.request.agent(app);
beforeEach(function (done) {
console.log('outer describe - beforeEach');
agent
.put('/api/ehrm-klantnr/medewerker/login')
.send({ email: 'admin#sfgtest.com', wachtwoord: '<secret>' })
.then(function (res) {
expect(res).to.have.cookie('SESSIONID');
done();
});
});
describe('Ophalen alle relaties met: GET /api/ehrm-klantnr/relatie', () => {
it('should get alle relaties', (done) => {
agent.get('/api/ehrm-klantnr/relatie')
.set('meta', '1')
.then(function (res) {
expect(res).to.have.status(200);
done();
});
});
});
});

How to delete the records entered to the MySql database during the tests run using Mocha and Chai

I have written a test program which can test number of endpoints written in node.js and check whether they 're working. I need a way to delete the records i entered to the database during the testing.
for example i need to delete the record added to the database after this test.
describe('/POST groups/AddGroupMember', () => {
before(function (done) {
setTimeout(function(){
done();
}, 5000);
});
let reqFields = {
"requestFields": {
"groupUID" : 50,
"custUID" : 20
}
}
it('it should ADD the group member', (done) => {
chai.request(server)
.post('/groups/AddGroupMember')
.send(reqFields)
.end((err, res) => {
var uid = res.body.uID;
console.log(uid);
res.should.have.status(200);
res.body.should.be.a('object');
done();
});
});
});

TypeError: Cannot read property 'remove' of undefined

I was working on a simple node project, and I came across this error. I can't seem to find a way through it, nor do I really understands what this means
const expect = require('expect');
const request = require('supertest');
const {app} = require('./../server');
const {Todo} = require('./../models/ToDo');
beforeEach((done) => {
Todo.remove().then(() => done());
});
describe('POST /todos', () => {
it('should create a new todo', (done) => {
var text = 'Test todo text';
request(app)
.post('/todos')
.send({text})
.expect(200)
.expect((res) => {
expect(res.body.text).toBe(text);
})
.end((err, res) => {
if(err) {
return done(err);
}
Todo.find().then((todos) => {
expect(todos.length).toBe(1);
expect(todos[0].text).toBe(text);
done();
}).catch((e) => done(e));
});
});
});
The error means your Todo is undefined. You can check like this.
beforeEach((done) => {
console.log(Todo); // put a breakpoint here if you want to inspect the variable
Todo.remove().then(() => done());
});

500 equals 400 passes in a mocha test?

Why does the following test pass?
"use strict";
const
path = require('path'),
Dexter = require('../src/Dexter.js'),
chai = require('chai'),
chaiHttp = require('chai-http'),
expect = chai.expect,
dexterServer = new Dexter(path.resolve(__dirname, 'test/data/sample.har'));
chai.use(chaiHttp);
describe('Rest API', () => {
before(() => {
dexterServer.startUp();
});
it('should\'ve started the server', function () {
chai.request('http://127.0.0.1:1121')
.get('/')
.end(function(err, response){
console.log(response.status);
expect(500).to.equal(400);// This passes? What?
done();
});
});
after(() => {
dexterServer.tearDown();
});
});
When I do a console.log of the response.status, I see a 200. But when I do
expect(response.status).to.equal(400);//response.status is an int
passes the test!
What am I doing wrong?
You forgot to pass done callback. it was treated as sync with 0 assumptions.
it('should\'ve started the server', function (done) {
chai.request('http://127.0.0.1:1121')
.get('/')
.end(function(err, response){
console.log(response.status);
expect(500).to.equal(400);// This passes? What?
done();
});
});
You have to pass done in it, before and after statement to maintain the asynchronous flow.
describe('Rest API', (done) => {
before(() => {
dexterServer.startUp();
});
it('should\'ve started the server', function (done) {
chai.request('http://127.0.0.1:1121')
.get('/')
.end(function(err, response){
console.log(response.status);
expect(500).to.equal(400);// This passes? What?
done();
});
});
after((done) => {
dexterServer.tearDown();
});
});
Mocha supports promises so you could use the fact that chai-http produces promises and just return the promise:
it('should\'ve started the server', function () {
// Return the promise.
return chai.request('http://127.0.0.1:1121')
.get('/')
// Use .then instead of .end.
.then(function(response){
console.log(response.status);
expect(500).to.equal(400);
});
});
If you need to do special processing of errors, you could have a .catch too. Otherwise, you can let Mocha handle any error as a failure.

Resources