Unable to start test using mocha - node.js

following is the error i am facing while running mocha tests...
upquire#0.0.0 test D:\tecsol\mtv
mocha test/bootstrap.test.js test/unit/**/*.test.js
1) "before all" hook
0 passing (3m)
1 failing
1) "before all" hook:
Error: timeout of 50000ms exceeded. Ensure the done() callback is being called in this test.
at null.<anonymous> (D:\tecsol\mtv\node_modules\mocha\lib\runnable.js:189:19)
The following is my bootstrap.test.js file:
var Sails = require('sails');
var sails;
before(function(done) {
this.timeout(5000);
Sails.lift({
// configuration for testing purposes
}, function(err, server) {
sails = server;
if (err) return done(err);
// here you can load fixtures, etc.
done(err, sails);
});
});
after(function(done) {
// here you can clear fixtures, etc.
Sails.lower(done);
});

Related

Mocha UnhandledPromiseRejectionWarning: AssertionError

I'm beginning start writing some Mocha tests for an application I've been working on.
When running onn of the tests fails I'm getting the following error:
(node:12988) UnhandledPromiseRejectionWarning: AssertionError: Failure reason: expected 'Fail' to include 'Success'
Whilst I understand the failure reason, I'm really struggling to resolve the UnhandledPromiseRejection warning and have gone round in circles with the issue.
Any ideas?
describe('Test', function() {
it('This should complete succesfully', function() {
class Obj {
getResult() {
return new Promise(function(resolve, reject) {
resolve('Fail');
});
}
}
var obj = new Obj();
obj.getResult().then(function(res) {
expect(res).to.include('Success');
});
});
});
The test is asynchronous and should be treated as such. Modern testing frameworks support promises, including Mocha. If there's a promise, it should be returned from test function:
return obj.getResult().then(function(res) {
expect(res).to.include('Success');
});

Integration tests sporadically timeout on Heroku hobby-dev

Since we do not get any helpful support from help.heroku.com we make the last try here.
We are developping a classic web app consisting of:
----- ----- ----
|WEB| <----> |API| <----> |DB|
----- ----- ----
We currently are working with the following Heroku Dynos/Datastores
Heroku Postgres: Hobby Basic
Heroku API Dyno: Hobby
Heroku WEB Dyno: Hobby
The tech stack is:
runtime: nodejs (4.4.0)
db: postgres (9.6.1)
testframework: jasminejs (2.5.1)
query builder: knexjs (0.10.0)
We recently moved to from self hosted docker environment to Heroku and configured the Herokus CI pipeline which works fine for unit testing - but not integration testing.
The tests sporadically fails with timeouts (in average every 3rd test of the same commit). This is not stable enough to build up CI/CD.
Here the error messages we get:
**************************************************
* Failures *
**************************************************
1) integration test collections repository create() should return AUTHENTICATION_REQUIRED if user is anonymous
- Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
- Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
2) integration test collections repository create() should return AUTHORIZATION_REQUIRED if user is not space MEMBER
- Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
- Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
- Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
3) integration test collections repository create() should return collection if user is space MEMBER
- Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
- Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
- Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
For testing purposes we configured knex connection pooling to use one connection only:
export default {
client: 'pg',
connection: DB_URL,
pool: {
max: 1,
min: 1
}
};
The typical integration test setup is:
describe('integration test', () => {
describe('collections repository create()', () => {
//////////////////////////////////////////////////////////////////////
//Before the test block is execute all fixtures are loaded into the DB
//////////////////////////////////////////////////////////////////////
beforeAll((callback) => {
seed(path.join(__dirname, 'fixtures'))
.then(callback)
.catch((error) => {
fail(error);
callback();
});
});
////////////////////////////////////////////////////////////////////////
//Truncate all data from the DB before the next test block gets executed
////////////////////////////////////////////////////////////////////////
afterAll(resetDB);
it('should return AUTHENTICATION_REQUIRED if user is anonymous', (callback) => {
testUtils.testAsync({
callback,
catchTest: (error) => {
expect(error).toEqual(jasmine.any(repositoryErrors.AUTHENTICATION_REQUIRED));
},
runAsync: create({ props: { space: { id: 1 } } })
});
});
it('should return AUTHORIZATION_REQUIRED if user is not space MEMBER', (callback) => {
testUtils.testAsync({
callback,
catchTest: (error) => {
expect(error).toEqual(jasmine.any(repositoryErrors.AUTHORIZATION_REQUIRED));
},
runAsync: create({ props: { space: { id: 1 } }, userId: 1 })
});
});
it('should return collection if user is space MEMBER', (callback) => {
testUtils.testAsync({
callback,
runAsync: create({ props: { space: { id: 1 } }, userId: 2 }),
thenTest: (outcome) => {
expect(outcome).toEqual({ id: '1' });
}
});
});
...
seed:
const tableOrder = [
'users',
'guidelines',
'collections',
'spaces',
'details',
'files',
'guidelinesAuthors',
'collectionsUsers',
'spacesUsers',
'guidelinesCollections',
'spacesCollections',
'guidelinesDetails',
'guidelinesFiles',
'comments',
'commentsReplies',
'notifications'
];
export default function seed(path) {
return db.raw('BEGIN;')
.then(() => {
return tableOrder.reduce((promise, table) => {
return promise
.then(() => slurp({ path, table }))
.then(() => {
updateIdSequence(table)
.catch((error) => {
// eslint-disable-next-line no-console
console.log(
`Updating id sequence for table '${table}' failed! Error: `,
error.message
);
});
});
}, Promise.resolve()).then(() => db.raw('COMMIT;'));
})
.catch((error) => {
// eslint-disable-next-line no-console
console.log('SEED DATA FAILED', error);
return db.raw('ROLLBACK;');
});
}
...
resetDB:
export default function resetDB(callback) {
const sql = 'BEGIN; '
+ 'SELECT truncateAllData(); '
+ 'SELECT restartSequences(); '
+ 'COMMIT;';
return db.raw(sql)
.then(callback)
.catch((error) => {
// eslint-disable-next-line no-console
console.log('TRUNCATE TABLES FAILED', error);
return db.raw('ROLLBACK;');
});
}
Until now, these test have been running on local machines (Linux/Mac) and Codeship without any problem.
After almost two weeks of trying to get this work we made zero progress on this issue. I can't see anything wrong with this configuration and I start to belive Heroku has a serious issue with the datastores...
Has anybody experienced similar issues on Heroku?
Any idea what we can try else to get this work?

npm run script: node server.js && mocha test

My use case is pretty simple:
First I want to run node server.js(start my Node.js app) - and after Node has started - I want to run mocha test (running some tests on the API provided by previous server.js) by executing npm run test.
The script: "test": "NODE_ENV=development node server.js && mocha test"
Node starts, but unfortunately the mocha testdoes not seem to be executed:
So how can I execute mocha test after node server.js?
The reason why you're running into this is because node server.js continuously runs until killed (Ctrl + C) or a fatal unhandled exception occurs. Since the node process keeps running mocha test never get executed.
One approach to this would be to use gulp as a task runner and utilize tasks implementing gulp-nodemon and gulp-mocha. If you've never used Gulp before or are unfamiliar with task runners I suggest you read the docs beforehand just to get an idea of how it works.
Add the gulpfile.js below to your app (adjust some of the settings as necessary) and modify your package.json scripts with the test script below and this should solve your issue.
gulpfile.js
var gulp = require('gulp');
var mocha = require('gulp-mocha');
var nodemon = require('gulp-nodemon');
gulp.task('nodemon', (cb) => {
let started = false;
return nodemon({
script: 'server.js'
})
.on('start', () => {
if (!started) {
started = true;
return cb();
}
})
.on('restart', () => {
console.log('restarting');
});
});
gulp.task('test', ['nodemon'], function() {
return gulp.src('./test/*.js')
.pipe(mocha({reporter: 'spec' }))
once('error', function() {
process.exit(1);
})
.once('end', function() {
process.exit();
});
});
package.json scripts
{
"scripts": {
"test": "NODE_ENV=development gulp test"
}
}
Supertest Alternative
A more elegant solution ,and in my opinion the better option, would be to rewrite your tests to use supertest. Basically what you do with supertest is pass your Express instance to it and run assertions tests against it with the supertest package.
var mocha = require('mocha');
var request = require('supertest');
var server = require('server');
describe('test server.js', function() {
it('test GET /', function(done) {
request(server)
.get('/')
.expect(200, done);
});
});
add this code to your test case
after(function (done) {
done();
process.exit(1);
})

Babel not working with Mocha and starting Node server

I am running sailsjs, mocha, and babel on sails and mocha. When I run, my before function to start the sails app before running tests, I get this:
> PORT=9999 NODE_ENV=test mocha --recursive --compilers js:babel/register
lifting sails
1) "before all" hook
0 passing (757ms)
1 failing
1) "before all" hook:
Uncaught Error: only one instance of babel/polyfill is allowed
For the life of me, I can't figure out how to make mocha running babel and sails running babel at the same time work.
My before() code looks like this:
import Sails from 'sails'
// Global before hook
before(function (done) {
console.log('lifting sails')
// Lift Sails with test database
Sails.lift({
log: {
level: 'error'
},
models: {
connection: 'testMongoServer',
migrate: 'drop'
},
hooks: {
// sails-hook-babel: false
babel: false
}
}, function(err) {
if (err) {
return done(err);
}
// Anything else you need to set up
// ...
console.log('successfully lifted sails')
done();
});
});
I use sails-hook-babel and it works like a charm. Here to do it:
Install npm install sails-hook-babel --save-dev
Edit your bootstrap.js/ before function to load babel, i.e.
var Sails = require('sails'),
sails;
var options = {
loose : "all",
stage : 2,
ignore : null,
only : null,
extensions: null
};
global.babel = require("sails-hook-babel/node_modules/babel/register")(options);
before(function (done) {
Sails.lift({
//put your test only config here
}, function (err, server) {
sails = server;
if (err) return done(err);
// here you can load fixtures, etc.
done(err, sails);
});
});
after(function (done) {
// here you can clear fixtures, etc.
sails.lower(done);
});
Now you are able to use ES6 within your tests.
Here is the reference:
Babel issue at GitHub
My Blog, sorry it written in Bahasa Indonesia, use Google translate if you want to.

Cannot read property '_host' of null when running supertest in node-inspector

I'm fairly new to the Angular world and have been using the angular-fullstack generator + Yeoman to build out a project. I'm using Sublime (not Webstorm) and have been trying to figure out how to set up the project so that I can debug the mocha tests from the terminal, but am hitting a wall.
Here's the default things.spec.js that's generated with 'yo angular-fullstack' with a debugger statement added in.
var should = require('should');
var app = require('../../app');
var request = require('supertest');
describe('GET /api/things', function() {
it('should respond with JSON array', function(done) {
request(app)
.get('/api/things')
.expect(200)
.expect('Content-Type', /json/)
.end(function(err, res) {
debugger;
if (err) return done(err);
res.body.should.be.instanceof(Array);
done();
});
});
});
By combining advice from the grunt-mocha-test documentation and this SO answer, I've updated the test script in package.json as follows:
"scripts": {
"test": "node-debug <PATH TO GRUNT-CLI>\\grunt test"
}
When I run 'npm test', node-inspector successfully boots up a browser instance and attaches the debug session to my test process. However, when I press "continue", the debugger breakpoint is NOT hit and the test fails with the following stack. Anyone have any clues as to what's causing this?
TypeError: Cannot read property '_host' of null
at ClientRequest.http.ClientRequest.onSocket (eval at WRAPPED_BY_NODE_INSPECTOR (\node_modules\node-inspector\node_modules\v8-debug\v8-debug.js:95:15), <anonymous>:381:28)
at new ClientRequest (http.js:1432:10)
at Object.exports.request (http.js:1843:10)
at Test.Request.request (\node_modules\supertest\node_modules\superagent\lib\node\index.js:615:28)
at Test.Request.end (\node_modules\supertest\node_modules\superagent\lib\node\index.js:677:18)
at Test.end (\node_modules\supertest\lib\test.js:123:7)
at Context.<anonymous> (\server\api\thing\thing.spec.js:14:8)
at Test.Runnable.run (\node_modules\grunt-mocha-test\node_modules\mocha\lib\runnable.js:196:15)
at Runner.runTest (\node_modules\grunt-mocha-test\node_modules\mocha\lib\runner.js:374:10)
at Runner.runTests.next (\node_modules\grunt-mocha-test\node_modules\mocha\lib\runner.js:452:12)
This looks like a bug in Node Inspector.
https://github.com/node-inspector/node-inspector/issues/698

Resources