I want to use mocha to add to my program feature by feature, test by test.
var assert = require('assert');
var mongoskin = require('mongoskin');
describe('basic database tests', function(){
before(function(){
});
it('should have 3 users', function(done){
var db = mongoskin.db('mongodb://localhost:27017/stuffTest', {safe:true});
db.collection('users').find().toArray(function (err,result){
console.log(result.length);
assert.equal(result.length,3);
});
});
});
It doesn't work. I get an error no matter where I put stuff in the test. With this arrangement I get Error: timeout of 2000ms exceeded
This is the code to set up the database. My old way of development was to litter my code with console.logs and such. This code uses console.logs to let me know if the collection is empty and then if so was it filled with 3 records.
var mongoskin = require('mongoskin')
var db = mongoskin.db('mongodb://localhost:27017/stuffTest', {safe:true})
db.collection('users').find().toArray(function (err,result){
console.log(result.length)
})
db.collection('users', {strict:true}, function(err, collection) {
if (err) {
console.log("The 'users' collection doesn't exist. Creating it with sample data...");
populateDB(users);
}
});
var populateDB = function(huh) {
console.log("Populating database...");
var name= huh.name;
var coll= huh.items;
db.collection(name, function(err, collection) {
collection.insert(coll, {safe:true}, function(err, result) {
console.log(result.length);
});
});
};
var users = [];
users.name = 'users';
users.items= [
{name: 'tim', email: 'mckenna.tim#gmail.com', lists:[]},
{name: 'peri', email: 'perimckenna#gmail.com', lists:[]},
{name: 'tim2', email: 'mckt_jp#yahoo.com', lists:[]}
];
How would I write this test? This code plus package.json and dropDb.js is here: https://github.com/mckennatim/tdd
You're not calling done. If you don't call done in an asynchronous test you are guaranteed to get a timeout. Modify the test to call done at the end of your callback. Like this:
it('should have 3 users', function(done){
var db = mongoskin.db('mongodb://localhost:27017/stuffTest', {safe:true});
db.collection('users').find().toArray(function (err,result){
console.log(result.length);
assert.equal(result.length,3);
done();
});
});
Related
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'm creating a unit test to test Passport, and the first step is to create a user. Creating the user times out and the test is unable to progress.
Test (login.js):
'use strict';
var app = require('../index'),
kraken = require('kraken-js'),
mongoose = require('mongoose'),
User = mongoose.model('User'),
should = require('chai').should(),
Q = require('q'),
agent = require('supertest'),
cookie,
pUser = {
firstName: 'pasport-test',
lastName: 'user',
userName: 'passport-user',
email: 'passport-user#here.com',
password: 'h#rdP#ssw0rd'
}
describe('#create user and log them in with passport', function () {
this.timeout(10000);
var mock;
beforeEach(function (done) {
kraken.create(app).listen(function (err, server) {
mock = server;
done(err);
});
});
afterEach(function (done) {
mock.close(done);
});
describe('#login the user', function () {
it('should create a user', function (done) {
var user = new User({
firstName: pUser.firstName,
lastName: pUser.lastName,
userName: pUser.userName,
email: pUser.email,
password: pUser.password
});
user.save(function(err, data) {
if(err) {
done(err);
} else {
done();
}
});
//it should then login that user with passport
});
});
If I connect o to mongoose directly:
mongoose.connect("mongodb://localhost/testing");
and require User this way:
User = require('../models/user');
It works.
I'd like to use the server and connection that the beforeEach sets up with kraken, so that inserts happen in the configured database...
Question is why does the mongoose insert never come back in the test?
You need to call mongoose.connect in your test code. mongoose queues all pending operations until a first db connection is made, which is why your save callback never gets called.
As noted by #Peter Lyons, I needed to perform the connect to the database.
I wrote a small helper to do this (that I can use across my test files).
db.js:
'use strict';
var nconf = require('nconf'),
mongoose = require('mongoose'),
env = process.env.NODE_ENV || 'testing';
//get the db config stuff for mongoose from the application config file
nconf.use('file', {
file: process.cwd() + '/config/app.json',
format: nconf.formats.json
});
var dbConf = nconf.get('databaseConfig')[env];
var db = function() {
return {
connect: function() {
if(!mongoose.connection.db) {
mongoose.connect("mongodb://" + dbConf.host + '/' + dbConf.database);
}
}
};
};
module.exports = db();
Then in my tests:
var db = require('./db');
db.connect();
And the model classes perform as expected.
I have been at this for hours and its like banging my head into a brick wall.
I have a node.js server application that uses mongoose to store data.
Now this all works amazingly but my problem is when I try and use Qunit to test my code I can get me mongoose save function to fire.
This is my unit test class.
mongoose.connect('mongodb://localhost/test');
var User = require('C:/SVN/RPGMMO/Server/Users/User');
QUnit.config.testTimeout = 50000;
QUnit.module("User", {
setup: function() {
user = new User();
ok(user != undefined, "Test Data Created");
},
teardown: function() {
user = undefined;
ok(user == undefined, "Test Data Deleted");
}
});
test("Create User", function() {
var user = new User({
name: 'test_user',
email: 'blah'
});
user.setPassword('test');
user.save(function(err, result) {
util.log("saving");
if (err) throw err;
ok (result, "Created User")
});
});
But when I run this test the user.save is never fired, only the setup and teardown is run.
Could anyone point out where am going wrong.
Am new to Quint on server side.
Regards
Iain
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.
In Node.js, I have (briefly) this script:
var http = require('http');
var XmlStream = require('xml-stream');
var mongo = require('mongodb');
var tims = { ... };
var db = new mongo.Db('tims', new mongo.Server("127.0.0.1", 27017, {}), {w: 1});
db.open(function(e, db) {
var req = http.get({
host: tims.uri,
path: '/xml/'+tims.database+tims.services.database
}).on('response', function(res) {
res.setEncoding('utf8');
cProjects = db.collection("projects");
var xml = new XmlStream(res);
xml.on('updateElement: Tims ProjectID', function(project) {
// console.log(project.$text+' - '+project.$.title);
cProjects.update({project_id: project.$text}, {project_id: project.$text, title: project.$.title}, {upsert:true}, function(err, result) {
console.log('result: '+result);
});
});
xml.on('end', function(data) {
db.close();
});
});
});
I am using a Node.js package called xml-stream that pieces together response chunks from Node to get valid XML before processing. My problem: if I leave out
xml.on('end', function(data) {
db.close();
});
my connection never closes and the console just hangs. The upside is that console.log('result: '+result); writes to the console and I can see that my data was committed successfully. So if I leave in the end event and close the DB once all XML has been processed, the Node instance terminates before console.log('result: '+result) is written.
I am a newbie to both MongoDB and Node.js, so I was curious what the best practice is here for confirmation, or perhaps a simple pointing out of what I'm doing wrong.
Thanks for the help.
Looks like the 'end' event is occurring before all the update callbacks have completed. So you need to rework your code a bit to keep track of the number of updates still pending and only call db.close() once both the 'end' event has fired and all the pending updates have completed.
So something like this:
db.open(function(e, db) {
var req = http.get({
host: tims.uri,
path: '/xml/'+tims.database+tims.services.database
}).on('response', function(res) {
res.setEncoding('utf8');
cProjects = db.collection("projects");
var xml = new XmlStream(res);
var end = false;
var pending = 0;
xml.on('updateElement: Tims ProjectID', function(project) {
// console.log(project.$text+' - '+project.$.title);
++pending;
cProjects.update({project_id: project.$text}, {project_id: project.$text, title: project.$.title}, {upsert:true}, function(err, result) {
console.log('result: '+result);
if (--pending === 0 && end) {
db.close();
}
});
});
xml.on('end', function(data) {
end = true;
});
});
});