XMight XMight -4 years ago 121
Node.js Question

Nodejs mocha unit test sqlite3 callback not called insert not executed

I want to create unit tests for my app. The API works just fine when calling it through browser, but when I want to execute the test, either with npm test, or mocha test, the callback function is not called and the INSERT statement doesn't get to be executed. I get no error. Code:

Unit test file:

process.env.NODE_ENV = 'test';
var chai = require('chai');
var chaiHttp = require('chai-http');
var server = require('../server/server');
var Const = require("../config/const.js");
var should = chai.should();
chai.use(chaiHttp);
var assert = chai.assert;

var column1value = "1234567890123456"

describe('All', function() {
it('Insert',function(done) {
chai.request(server)
.post('/' +Const.SERVER_NAME + '/insert')
.set('content-type', 'application/x-www-form-urlencoded')
.send({param1: column1value, param2: 'true'})
.end(function(err, res){
console.log(new Date().getTime() + "!1");

res.should.have.status(200);

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


Database manager insert method:

method.insert = function(param1, param2) {
openDb();

console.log("blabla1");
console.log("param1:" + param1 + ";param2:" + param2);

db.run("INSERT INTO mytable (column1, column2) values (?,?)",param1,param2, function(err) {

console.log("blabla2" + this);

if (err) {
console.log(err);
} else {
console.log("Successfuly updated: " + param1);
}
});

db.close();

console.log("blabla3");
};


What I get in console output when I run "npm test" or "mocha test":

blabla1

param1:1234567890123456;param2:true

blabla3

timestamp!1

If I start the nodejs server and using, let's say, postman, call the API that calls the insert, the data is inserted into the Database and blabla2 log is shown.
What I'm missing?

UPDATE

The problem is related to what Alexandru Olaru has written, but to be more specific, I was doing in the index.js (where are my routes)

function insertOrUpdateData(req, res) {
databaseManager.insert(req.body.param1, req.body.param2);
res.end();
return;
};


but I needed to do:

function insertOrUpdateData(req, res) {
databaseManager.insert(req.body.param1, req.body.param2, function (err) {
logger.log("*-*-router insert callback");
res.end();
return;
});
}


Related why the problem is reproducible only in unit tests from what I understand right now is because the asynchronous task is executed in node after all, but in unit test it isn't. Why it isn't in unit test, I'm not yet very sure (Can be related to unit test lifecycle or interaction with node instance).

Answer Source

Refactor your code to use a callback or a promise:

method.insert = function (param1, param2) {
  return new Promise((resolve, reject) => {
    openDb();
    db.run('INSERT INTO mytable (column1, column2) values (?,?)', param1, param2, (err) => {
      db.close();
      if (err) {
        reject(err);
      } else {
        resolve();
      }
    });
  });
};

handler.insert(param1, param2)
  .then(() => { // the stuff after })
  .catch((err) => { // handler error });

The problem is in the fact that you are not setting an callback for the asynchronous part.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download