I have an express-sequelize application, it uses nodeunit to test routes and for this I use the wonderfull nodeunit-express module.
All works fine, except sequelize creating the database. In my express app I do a sequelize.sync({force: true}) during the start.
My tests do work when I run
npm start (node server.js)
first, followed by
npm test (nodeunit test)
But when the database is not present and I run
npm test (nodeunit test)
Alone, the is not created errors.
Where in the nodeunit testing process should I place the sync sequelize to have it available for my tests?
var request = require('nodeunit-express');
var server = require('../server');
var models = require('../models');
var express = request(server.app);
exports["Rest interfaces"] = {
setUp: function (callback) {
//insert some stuff in the database?
callback();
},
tearDown: function (callback) {
callback();
//cleanup();
},
"/api/categories": function (test) {
express.get('/api/categories').expect(function (response) {
// response is the response from hitting '/'
var result = JSON.parse(response.body);
test.equal(response.statusCode, 200, '/api/categories is not available');
test.equal(result.length, 0, 'no categories should be returned');
test.done();
});
}
};
function cleanup() {
//wait a little
setTimeout(function () {
express.close();
}, 500);
}
Related
currently I try to figure out, how I can run mocha tests on a GET request of localhost:3000/run/tests resource.
Most things seems to work fine, but mocha .on('end') is probably not fired correctly so my res.json(...) function is not called and node still hangs.
var Mocha = require('mocha');
...
app.get('/run/tests', (req, res) => {
var mocha = new Mocha({
reporter: 'json'
});
myTestFiles.forEach(testfile => mocha.addFile('./tests/' + testfile + '.js'));
mocha.run()
.on('end', function() {
console.log(this.testResults);
res.json(this.testResults);
});
});
I get expected output except the "0 passing" lines :
> ...
> CALL element.text()
> GET /session/:sessionID/element/9/text
> RESPONSE element.text() "Username"
√ App login finished: 37685ms
0 passing (0ms)
0 passing (16ms)
My testfile looks like this:
'use strict';
require('./helpers/setup');
var wd = require('wd');
var serverConfigs = require('./helpers/appium-servers');
describe('Carnet App', function () {
this.timeout(120000);
var driver;
var allPassed = true;
before(function () {
var serverConfig = serverConfigs.local;
driver = wd.promiseChainRemote(serverConfig);
require('./helpers/logging').configure(driver);
var desired = {
'appium-version': '1.4.16',
platformVersion: '6.0.1',
device: 'Android',
platformName: 'Android',
app: myapp.apk'
};
return driver
.init(desired)
.setImplicitWaitTimeout(120000);
});
after(function (done) {
return driver
.quit()
.done();
});
afterEach(function () {
allPassed = allPassed && this.currentTest.state === 'passed';
});
it('App login finished', function () {
return driver
.elementById('...')
.click()
.sendKeys('...')
.elementById('...')
.text().should.become('Username');
});
});
Do I make a mistake? Does anybody have expirence with wd + mocha programmatically? Thanks for help!
Ok I solved my problem by only modify the following:
mocha.run(function(failures){
res.json({ ... })
})
.on('test', function() {
// do some logging stuff (into a var retured by res.json above)
})
// ... all mocha events possible
// see https://github.com/mochajs/mocha/blob/master/lib/runner.js#L49
.on('test end', function() {
// do some advanced logging stuff
});
I'm trying to run some test implying Moongoose and database calls using Mocha and Chai but the test fails at the database request with no warning at all. I might be making a mistake somewhere.
Here is the test file:
'use strict';
process.env.NODE_ENV = 'test';
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/dbtest', function(err, res) {
if(err) {
console.log('Error connecting to the database. ' + err);
} else {
console.log('Connected to Database: ' + config.mongoURI[app.settings.env]);
}
});
var chai = require('chai');
var expect = chai.expect; // we are using the "expect" style of Chai
var ScoreAction = require('./../../model/GTscoreAction.js');
describe('ScoreAction', function() {
it('newFriend', function() {
expect(ScoreAction.addNewFriend(12, 155).toEqual(1));
});
});
And the GTscoreAction.js method:
ScoreActionSchema.statics.addNewFriend = function(userID, friendFacebookID) {
ScoreAction.findOne({
_user: userID,
type : 1,
data: friendFacebookID
}).exec(function(err, sa) {
if (sa)
return 0;
return 1;
});
}
This always fails on the "ScoreAction.findOne" with no warning or error.
Many thanks for any help!
The return 1; actually is not the return value of addNewFriend() function. There is a function inside .exe(), can you see it? :)
So, I'm trying to run a Mocha test, more precisely a Chakram test.
The problem is, I'm getting data from a collection in MongoDB and I want to store that data in a global variable to run some tests.
The problem is that inside the call back I get the data, but it doesn't set the global variables to run the tests.
Here is the code
var chakram = require('chakram'),
expect = chakram.expect;
describe("Test", function() {
var gl_email;
var gl_token;
before("Getting user data", function() {
var setAccessData = function() {
var MongoClient = require('mongodb').MongoClient;
MongoClient.connect('mongodb://localhost/virtusapp', function(err, db) {
if (err) throw err;
console.log("Connected to Database");
var user = db.collection('users').findOne({
name: "virtus-app"
});
user.then(function(result) {
email = result.email;
token = result.token1 + result.token2;
db.close(test(email, token))
});
});
}
var test = function(email, token) {
gl_email = email;
gl_token = token;
//Here the email and token are set, but it doesnt set the global variables
}
setAccessData();
});
it("should have set global email variable", function() {
//here gl_email should be set, but I get UNDEFINED.
expect(gl_email).to.eql("virtus-app#virtus.ufcg.edu.br");
})
});
I believe that the problem is not with Chakram, because I haven't used in this code yet.
Your before function is asynchronous. You should use a different signature to tell mocha that it has to wait until it's finished before running the tests.
before("Getting user data", function(done) {
...
var test = function(email, token) {
gl_email = email;
gl_token = token;
done();
}
...
});
Only after done() is called the rest of the code is going to be executed by mocha.
Mocha docs has a very comprehensive guide on how to test asynchronous code https://mochajs.org/#asynchronous-code
I am having trouble writing tests for my objects using mocha. The code appears to work in practice but during my tests, database updates are happening later than expected. During test setup I insert a few records into a collection. In the teardown I clear the collection. When I search for a known record I get zero results unless I recursively invoke the callback function (as shown in the code below).
Everything is written asynchronously. The setup function returns all the records. Somehow it seems that the data is not refreshed quickly enough. Can anyone advise if I am approaching this correctly with the recursive loop?
var myclass = require('myclass')
var mongoose = require('mongoose');
var should = require('should');
mongoose.connect('mongodb://localhost/myDbTests');
mongoose.connection.on('error', console.error.bind(console, 'connection error:'));
describe('Test my collection.', function () {
beforeEach('load dummy data into the database', function (done) {
myclass.load_data(dummyData, function (count) {
count.should.be.greaterThan(5);
done();
});
});
afterEach('clear the database', function (done) {
myclass.model.remove({}, function() {
done();
});
});
it('check that a known record exists database', function (done) {
var keep_checking = function (td) {
if (!td) {
myclass.get_record('MYRECORD', keep_checking);
} else {
td.should.have.property('category', 'someCategory');
done();
}
}
keep_checking(0);
});
});
My load_data is:
var _load_data = function (data, callback) {
data.forEach(function (d) {
var rec = new _model(d);
rec.save(function(err, res) {
if (err) return console.error(err);
});
});
callback(data.length);
};
You should wait until the database connection is open to run your tests.
I achieve that in my tests with the before hook which runs before any test (and before beforeEach as well):
before(function(done) {
mongoose.connection.once('open', done);
}
That will prevent anything from being run before the database connection is open.
I was not loading the data correctly. Mongoose does not allow multiple record insertion so I had used a synchronous .forEach loop to save each object. A better way to do, and hence my solution, is the following:
var _load_data = function (data, callback) {
var total = data.length,
count = 0;
function saveAll() {
var doc = data[count];
var rec = new _model(doc);
rec.save(function(err, res) {
if (err) {
throw err;
}
if (count !== total) {
count += 1;
saveAll();
} else {
callback(count);
}
});
}
saveAll();
};
I am writing nodeunit tests for operations around a mongodb. When I execute my test with nodeunit (nodeunit testname.js), the test runs through and goes green but the nodeunit command line doesn't return (I need to hit ctrl-c).
What am I doing wrong? Do I need to close my db connection or the server or is my test wrong?
Here is a cutdown sample test.
process.env.NODE_ENV = 'test';
var testCase = require('/usr/local/share/npm/lib/node_modules/nodeunit').testCase;
exports.groupOne = testCase({
tearDown: function groupOneTearDown(cb) {
var mongo = require('mongodb'), DBServer = mongo.Server, Db = mongo.Db;
var dbServer = new DBServer('localhost', 27017, {auto_reconnect: true});
var db = new Db('myDB', dbServer, {safe:false});
db.collection('myCollection', function(err, collectionitems) {
collectionitems.remove({Id:'test'}); //cleanup any test objects
});
cb();
},
aTest: function(Assert){
Assert.strictEqual(true,true,'all is well');
Assert.done();
}
});
Michael
Try putting your cb() within the remove() callback after you close you connection:
var db = new Db('myDB', dbServer, {safe:false});
db.collection('myCollection', function(err, collectionitems) {
collectionitems.remove({Id:'test'}, function(err, num) {
db.close();
cb();
});
});
You need to invoke cb function after the closure of db (during the tearDown):
tearDown: function(cb) {
// ...
// connection code
// ...
db.collection('myCollection', function(err, collectionitems) {
// upon cleanup of all test objects
db.close(cb);
});
}
This works for me.