I am somewhat new to the mocha framework. This code should throw an exception, but doesn't. (put all code in the test for simplicity)
describe("Test", function() {
it("this should throw an error", function() {
var Sequelize = require("sequelize");
var sequelize = new Sequelize({
dialect: 'sqlite',
storage: 'test.sqlite3'
});
var foo = sequelize.define('Foo', {
var_a: Sequelize.INTEGER,
var_b: Sequelize.STRING
});
sequelize.sync().then(function(err) {
throw('should throw an error here); // !!! Should throw an exception here
});
});
});
Interestingly, when I run the code straight in node.js (without the "describe" and "it" lines, of course), it raises an exception like it should. I am somewhat new to mocha, is there something incredibly simple that I'm missing?
Found the solution. From (https://mochajs.org/#getting-started): "By adding a callback (usually named "done") to it(), Mocha will know that it should wait for this function to be called to complete the test."
describe("Test", function() {
it("this should throw an error", function(done) {
var Sequelize = require("sequelize");
var sequelize = new Sequelize({
dialect: 'sqlite',
storage: 'db/test_db.sqlite3'
});
var foo = sequelize.define('Foo', {
var_a: Sequelize.INTEGER,
var_b: Sequelize.STRING
});
sequelize.sync().then(function(err) {
done();
throw('got here');
});
});
});
Related
I'm using nightwatchjs and the ssh2 npm package to test that a file name is present in a location, and asserting that it's correct.
My code is as follows;
var Client = require('ssh2');
var conn = new Client();
var longFileNamePrdArray;
module.exports = {
before:
conn.on('ready', function(browser) {
console.log('Client :: ready');
conn.sftp(function(err, sftp) {
if (err) throw err;
sftp.readdir('parkersreviewcontent/', function (err, list) {
if (err) throw err;
list.map(a => a.longname);
longFileNamePrdArray = list[1].longname;
conn.end();
});
});
})
.connect({
host: '*hostname*',
port: 22,
user: '*user*',
password: '*password*',
}),
'Test Zen Reviews production file is listed': function (browser) {
console.log(longFileNameStgArray);
},
'Closing the browser': function (browser) {
browser.browserEnd();
},
};
However, this results in undefined being outputted for longFileNamePrdArray.
If I move the console.log command inside the before code block, then the filename is correctly displayed as follows;
-rwxr--r-- 1 - - 2492238 Feb 28 06:37 parkers-reviews-staging.xml
but when I move it outside the before block and into my test block, it fails with the undefined output.
I thought by defining longFileNamePrdArray and stating it at the beginning of the test script it work 'carry across' the longFileNamePrdArray value into the test block, but it's not.
Any help and assistance would be really appreciated. Thanks.
I fixed this by using the done callback.
So my working code looks like this;
var Client = require('ssh2');
var conn = new Client();
var longFileNamePrdArray;
module.exports = {
before: function(browser, done) {
conn.on('ready', function(browser) {
console.log('Client :: ready');
conn.sftp(function(err, sftp) {
if (err) throw err;
sftp.readdir('parkersreviewcontent/', function (err, list) {
if (err) throw err;
list.map(a => a.longname);
longFileNamePrdArray = list[1].longname;
conn.end();
done();
});
});
})
.connect({
host: '*hostname*',
port: 22,
user: '*user*',
password: '*password*',
}),
'Test Zen Reviews production file is listed': function (browser) {
console.log(longFileNameStgArray);
},
'Closing the browser': function (browser) {
browser.browserEnd();
},
};
I have tried to insert the value in db in my mocha test i am getting this error i tried few of the following ways but nothing work out.
var assert=require('chai').assert;
const user=require('../model/user')
i tried both way
describe('insertDataLasone',()=>{
it('should save the value ',(done)=>{
var User = new user({fname:'test'});
User.save().then(done=>{
done()
}).catch(done=>done())
})
})
describe('User', function() {
describe('#save()', function() {
// this.timeout(5000)
it('should save without error', function(done) {
var User5 = new user({fname:'test'});
User5.save(function(done) {
if (err) done(err);
else setTimeout(done,3000);
});
});
});
});
This error occurs when done() is not called in a test. Make sure you are calling done().
var assert = require('chai').assert;
const User = require('../model/user');
describe('insertDataLasone', () => {
it('should save the value ', done => {
var user = new User({ fname: 'test' });
user.save().then(() => {
done();
})
.catch(done); // mocha done accepts Error instance
});
});
or
var assert = require('chai').assert;
const User = require('../model/user');
describe('User', function() {
describe('#save()', function() {
it('should save without error', function(done) {
var user5 = new User({ fname: 'test' });
user5.save(function(err) {
if (err) done(err);
else done();
});
});
});
});
Read https://mochajs.org/#asynchronous-code carefully
This question already has answers here:
node.js how to get better error messages for async tests using mocha
(2 answers)
Closed 5 years ago.
While writing tests for a project with Mocha & Chai I noticed I could get true.should.be.false to fail, but when the variable under test came from a promise and that expectation failed, Mocha would time out: Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.
Here are the examples of things I tried (and the solution) in hopes that it'll help someone in the future.
const chai = require('chai');
const should = chai.should();
const assert = chai.assert;
function getFoo() {
return new Promise((resolve, reject) => {
resolve({bar: true});
});
}
describe('Example for StackOverflow', function() {
it('will fail as expected', function() {
true.should.be.false;
});
it('will also fail as expected', function() {
var foo = {
bar: true
};
foo.bar.should.be.false;
});
it('times out instead of fails', function(done) {
getFoo().then(data => {
data.bar.should.be.false;
done();
});
});
it('times out instead of fails even without arrow notation', function(done) {
getFoo().then(function(data) {
data.bar.should.be.false;
done();
});
});
it('should throws an error when the expectation fails, but the done() in catch() doesnt seem to matter', function(done) {
getFoo().then(data => {
data.bar.should.be.false;
done();
})
.catch(error => {
console.error(error);
done();
})
.catch(error => {
console.error(error);
done();
});
});
it('still throws an error in the catch() if I try to use assert.fail() inside the catch to force a failure', function(done) {
getFoo().then(data => {
data.bar.should.be.false;
done();
})
.catch(error => {
console.error(error);
assert.fail(0, 1);
done();
})
.catch(error => {
console.error(error);
done();
});
});
});
For reference, here are the versions at play here:
node: v5.12.0
chai: v4.1.0
mocha: v3.4.2
This is different from node.js how to get better error messages for async tests using mocha in that I'm specifically talking about a timeout that occurs when should detects a failure and throws an error that isn't caught because the promise is not returned. Their solution focuses on using done- mine does not need it because it's returning the promise to Mocha so that it can catch the error.
The solution is to return the promise in the test function - I wasn't doing that in my times out instead of fails examples, and I noticed it later while writing up my examples to ask this question.
const chai = require('chai');
const should = chai.should();
const assert = chai.assert;
function getFoo() {
return new Promise((resolve, reject) => {
resolve({bar: true});
});
}
describe('Example for StackOverflow', function() {
it('needs to return the promise for the test runner to fail the test on a thrown exception - no done necessary', function() {
return getFoo().then(data => {
data.bar.should.be.false;
});
});
});
I am trying to write unittests for a loopback model using jasmine. My model has the usual CRUD endpoints but I have defined a custom '/products/:id/upload' endpoint which expects a form with files.
My model looks like
'use strict';
var loopback = require('loopback');
var ProductSchema = {
location: {
type: String,
required: true
},
version: {
type: String,
required: true
},
id: { type: Number, id: 1, generated: true }
};
var opts = {
strict: true
};
var dataSource = loopback.createDataSource({
connector: loopback.Memory
});
var Product = dataSource.createModel('Product', ProductSchema, opts);
Product.beforeRemote('upload', function(ctx){
var uploader = function(req, res){
// parse a multipart form
res({
result:'success'
});
};
function createProduct(uploaderResult){
// create a product out of the uploaded file
ctx.res.send({
result: uploaderResult.result
});
}
uploader.upload(ctx.req, createProduct);
});
Product.upload = function () {
// empty function - all the logic takes place inside before remote
};
loopback.remoteMethod(
Product.upload,
{
accepts : [{arg: 'uploadedFiles', http: function(ctx){
return function() {
return { files : ctx.req.body.uploadedFiles, context : ctx };
};
}},
{arg: 'id', type: 'string'}],
returns : {arg: 'upload_result', type: String},
http: {path:'/:id/upload', verb: 'post'}
}
);
module.exports = Product;
My end goal is to test the logic of the "createProduct".
My test looks like
'use strict';
describe('Product Model', function(){
var app = require('../../app');
var loopback = require('loopback');
var ProductModel;
beforeEach(function(){
app = loopback();
app.boot(__dirname+'/../../'); // contains a 'models' folder
ProductModel = loopback.getModel('Product');
var dataSource = loopback.createDataSource({
connector: loopback.Memory
});
ProductModel.attachTo(dataSource);
});
it('should load file ', function(){
console.log(ProductModel.beforeRemote.toString());
console.log(ProductModel);
ProductModel.upload();
});
});
By calling ProductModel.upload(); I was hoping to trigger the before remote hook which would exercise the the createProduct. I could test "createProduct" in isolation but then I would omit the fact that createProduct ends up being called as a result of upload.
To be perfectly clear, the core question is:
How do I exercise remote method hooks inside unittests ?
It was suggested to use supertest as an http server. Below there is a code snippet illustrating how to do it in jasmine
describe('My product suite', function(){
var request = require('supertest');
var app;
beforeEach(function(){
app = loopback();
// don't forget to add REST to the app
app.use(app.rest());
});
it('should load file', function() {
request(app).post('/products/id-of-existing-product/upload')
.attach('file', 'path/to/local/file/to/upload.png')
.expect(200)
.end(function(err, res) {
if (err) return done(err);
// res is the HTTP response
// you can assert on res.body, etc.
});
});
});
When using mocha to test a model of a sails app, It doesn't seem to run tests inside a callback:
var assert = require('assert');
describe('Dataset', function() {
describe('create', function() {
it('should create a new dataset', function() {
Dataset.create({
'name': 'testDataSet',
'description': 'This dataset exists for testing purposes only.',
'visibility': 'private',
'data': {
"foo": {
"barn": "door",
"color": "green"
}
}
}, function(err, dataset) {
assert(false);
});
});
});
});
This test is called by a script that initializes sails for it.
when Running this test, it passes, even though it should fail.
$: mocha
1 passing (875ms)
Also it never seems to run the callback containing assert(false). Placing assert false at any other location yields the exepcted results, also sails seems to be running properly.
Any help is greatly appreciated.
Your code is asynchronous, so you should use callback in your testing function:
var assert = require('assert');
describe('Dataset', function() {
describe('create', function() {
it('should create a new dataset', function(done) {
Dataset.create({
'name': 'testDataSet',
'description': 'This dataset exists for testing purposes only.',
'visibility': 'private',
'data': {
"foo": {
"barn": "door",
"color": "green"
}
}
}, function(err, dataset) {
if (err) throw err;
done();
});
});
});
});
Add assert call wherever you need.
There are a lot of examples here.