Mocha tests cases not waiting before to complete - node.js

I'm writing test cases with mocha in Nodejs and want to reset database data before running the tests. I'm using Knex as query builder for executing queries.
I wrote following logic:
describe('Activities:', function() {
before(funtion(){
activityDBOperations.deleteAll()
.then(function(){
// all records are deleted
});
});
it('it should add a record into Activities table: multiple time activity', function(done) {
activityDBOperations.addRecord(requestParams)
.then(function(data) {
expect(data.length > 0).to.equal(true);
done();
});
});
});
The problem is that test cases start executing and not waiting for deleteAll operation to finish. What I understand is since deleteAll is returning promise, the program execution move forward because of asynchronous nature of promises.
How can I make sure that test cases should run only when deleteAll has finished?

Either provide a callback to your before hook and call it in then:
before(function(done) {
activityDBOperations.deleteAll()
.then(function() {
// all records are deleted
done();
});
});
or, according to Mocha docs, just return a promise from before:
before(function() {
return activityDBOperations.deleteAll();
});

Add return statements so the Promises are actually returned.

Related

Unit Testing using mocha, node

I'm new to unit testing in the Node world and am struggling with this: I've setup a after cb to delete the records I've added during my tests, however I keep getting an error Error: done() called multiple times every time I delete the record on the db. Here's my code:
after((done) => {
User.deleteOne({email: user_email}, function(err, result) {
if(err) console.log(err);
console.log(result);
done();
});
});
If I do anything else (like just console something within the after block, I get no error at all.
What am I doing wrong?
Try with async/await style.
after(async () => {
const deleteResult = await User.deleteOne({email: user_email});
console.log(deleteResult);
});
With async/await you don't need to execute done, because mocha automatically handle promises.
More here and here

Webdriver.io - how to use beforeEach hooks in the config

I am building an app using the MEAN stack and Webdriver for testing.
At the moment I am cleaning the database between tests by using Mocha's beforeEach and afterEach hooks, e.g.:
describe('Links', function() {
// drop DB collections
beforeEach(function(done){
//create database objects
});
afterEach(function(done){
// drop DB collections
});
});
Is there a way of setting up wdio.conf.js for this to happen before and after each of my tests automatically? The config's before: and after: function() {} run as a beforeAll / afterAll rather than for each test.
Yes, see this url: http://webdriver.io/guide/testrunner/gettingstarted.html
if you launch the wdio config, will generate a file named wdio.conf.js, on this file exists functions to launch scripts after or before the tests, i show the example of the functions contains this file:
// =====
// Hooks
// =====
// Run functions before or after the test. If one of them returns with a promise, WebdriverIO
// will wait until that promise got resolved to continue.
//
// Gets executed before all workers get launched.
onPrepare: function() {
// do something
},
//
// Gets executed before test execution begins. At this point you will have access to all global
// variables like `browser`. It is the perfect place to define custom commands.
before: function() {
// do something
},
//
// Gets executed after all tests are done. You still have access to all global variables from
// the test.
after: function(failures, pid) {
// do something
},
//
// Gets executed after all workers got shut down and the process is about to exit. It is not
// possible to defer the end of the process using a promise.
onComplete: function() {
// do something
}
Is important, if you launch a script asynchronous, and you wait the callback in the moment of clean the database so you need a promise, else the next step hook will launch not waiting the previous function hook, example:
onPrepare: function() {
return new Promise(function(resolve, reject) {
sauceConnectLauncher({
username: 'the_pianist2',
accessKey: '67224e83a-1cf7440d-8c88-857c4d3cde49',
}, function (err, sauceConnectProcess) {
if (err) {
return reject(err);
}
console.log('success');
resolve();
});
});
},

Difficulty testing asynchronous function

I'm trying to learn Mocha and am having trouble dealing with asynchronous code.
I would like to create a test database, populate it with some data, and then write some tests. My issue is that I can not figure out how to require that my test database be created and populated before additional tests are run. Here's the basic structure of my code:
describe('Database', function() {
// create the DB and populate it with some test data
iniDB(dbName, function(db) {
addDataToDB(db, table, data);
});
// tests below here
});
From reading the documentation, it seems that I need to use before to ensure that my asynchronous code runs prior to my tests. To attempt this, I tried using something like this:
describe('Database', function() {
before(function(done) {
iniDB(dbName, function(db) {
addDataToDB(db, table, data);
});
done();
});
// tests below here
});
How can I tell Mocha to first create and populate my database before running subsequent tests?
Using before() is the right solution, just invoke done() when all your data has finished writing. Something like this:
before(function(done) {
iniDB(dbName, function(db) {
addDataToDB(db, table, data, function() {
done();
});
});
});

Mocha beforeEach and afterEach during testing

I have been trying to test my test server using mocha. This is the following code that I use, almost the same as one found in another similar post.
beforeEach(function(done) {
// Setup
console.log('test before function');
ws.on('open', function() {
console.log('worked...');
done();
});
ws.on('close', function() {
console.log('disconnected...');
});
});
afterEach(function(done) {
// Cleanup
if(readyState) {
console.log('disconnecting...');
ws.close();
} else {
// There will not be a connection unless you have done() in beforeEach, socket.on('connect'...)
console.log('no connection to break...');
}
done();
});
describe('WebSocket test', function() {
//assert.equal(response.result, null, 'Successful Authentification');
});
the problem is that when I execute this draft, none of the console.log that is expected to be seen is visible on the command prompt. Can you please explain to me what am I doing wrong?
Georgi is correct that you need an it call to specify a test but you don't need to have a top level describe in your file if you don't want to. You could replace your single describe with a bunch of it calls:
it("first", function () {
// Whatever test.
});
it("second", function () {
// Whatever other test.
});
This works very well if your test suite is small and composed of only one file.
If your test suite is bigger or spread among multiple files, I would very strongly suggest you put your beforeEach and afterEach together with your it inside the describe, unless you are absolutely positive that every single test in the suite needs the work done by beforeEach or afterEach. (I've written multiple test suites with Mocha and I've never had a beforeEach or afterEach that I needed to run for every single test.) Something like:
describe('WebSocket test', function() {
beforeEach(function(done) {
// ...
});
afterEach(function(done) {
// ...
});
it('response should be null', function() {
assert.equal(response.result, null, 'Successful Authentification');
});
});
If you do not put your beforeEach and afterEach inside describe like this, then let's say you have one file to test web sockets and another file to test some database operations. The tests in the file that contains the database operation tests will also have your beforeEach and afterEach executed before and after them. Putting the beforeEach and afterEach inside the describe like shown above will ensure that they are performed only for your web socket tests.
You have no tests in your example. If there are no tests to be run, then before and after hooks won't be invoked. Try adding a test like:
describe('WebSocket test', function() {
it('should run test and invoke hooks', function(done) {
assert.equal(1,1);
done();
});
});
You need to have a test-callback(eg. it) inside suite-callback(eg, describe) to execute beforeEach() and afterEach() hooks. More info https://mochajs.org/#run-cycle-overview

Mocha failed assertion causing timeout

I'm getting started with mocha testing framework with NodeJS. Success assertions working fine but if the assertion fails, my test timeouts. For asserting I've tried Should and Expect. For example (async code)
it('should create new user', function(done){
userService.create(user).then(function(model){
expect(model.id).to.be(1); //created user ID
done();
}, done)
});
Here the if model id is not 1 then the test timesout instead of reporting failed assertion. I'm sure I'm doing something wrong. Appreciate your help. Thanks!
Shawn's answer works, but there is a simpler way.
If you return the Promise from your test, Mocha will handle everything for you:
it('should create new user', function() {
return userService.create(user).then(function(model){
expect(model.id).to.be(1); //created user ID
});
});
No done callback needed!
expect is throwing an error that is being caught by the promise. Adding a catch condition that calls done fixes this.
it('should create new user', function(done) {
userService.create(user).then(function(model) {
expect(model.id).to.be(1); //created user ID
done();
}).catch(function(e) {
done(e);
})
});
Looks like done is never called. Besides then, you may also need an else to handle the failure.

Resources