I wish doing a test for ARI ! but i cant have a request for connection with asterisk . whene i run my file with node its ok , but if i run it with mocha no result !
let chai = require('chai');
let request = require('request');
let uuid = require('uuid');
let should = chai.should();
let ari = require('ari-client');
let expect = chai.expect;
let sinon = require('sinon');
describe('Tests originationDevice ', function () {
it(" should make a call ", function (done) {
ari.connect("http://192.168.0.62:8088", "username", "password")
.then(function (ari) {
console.log('its okey');
})
.catch(function (err) {
console.log('errrror');
});
done();
});
});
Well, its just one of solution but strongly recommend to mock external api calls-
try-
it(" should make a call ", function (done) {
ari.connect("http://192.168.0.62:8088", "username", "password")
.then(function (ari) {
console.log('its okey');
res.should.true; // something like that.
done(); // calling done function
})
.catch(function (err) {
console.log('errrror');
// assert something
done(); // call done function
});
});
Related
const request = require('supertest');
const app = require('../app');
request(app)
.get("/videos")
.expect(200)
.end(async (err,res) => {
if (err) {
console.error(err);
done();
} else {
console.log(res.body);
done(); // <- this is the question line
}
If I take off the done from the code, the test will print the result, but if I have done there, sequelize still print but there is no res.body print on the console.
Anyone knows why?
I think it's because of the asynchronous nature of javascript.
By default, Jest tests complete once they reach the end of their execution. That means this test will not work as intended:
const request = require('supertest');
const app = require('../app');
request(app)
.get("/videos")
.expect(200)
.end(async (err,res) => {
if (err) {
console.error(err);
// done();
} else {
console.log(res.body);
// done();
}
The problem is that the test will complete as soon as function completes asynchronosly.
Moving to, after putting done()
const request = require('supertest');
const app = require('../app');
request(app)
.get("/videos")
.expect(200)
.end(async (err,res) => {
if (err) {
console.error(err);
done();
} else {
console.log(res.body);
done();
}
And then, in that case, it waits for the done function before finishing the test.
For more details. Please check here.
I hope it helps. Thanks
Try to remove async from .end(async (err,res) => { line so the callback is not considered asynchronous anymore.
I am new to nodejs.
How do I stub my return result which is a callback.
I know that I should not access the DB when doing testing.
I am doing unit testing at the controller level.
Here is my flow on how I going to do my test based on my understanding from java.
Mock Request and Response.
Set param of request.
Mock bookDAO.selectBook so that it return a user defined result. Thus not calling DB.
Verify / assert the value of the return results. (i.e. Response must be 200, JSON format, must have column BOOK_ID, BOOK_TITLE, etc)
However, i was not able to successfully mock my function. After running npm test, this is the error that I am receiving.
2018-10-02T10:00:17.809 1) Book service
1. should list a SINGLE Book /book/id GET:
Error: selectBook cannot yield to '[object Object]' since no callback was passed. Received [XCV1234, function (result) {
res.status(200).json({
message: format(message.DEFAULT_MSG, "GET", constant.MODULE_URL),
result: result
});
}]
at throwYieldError (node_modules\sinon\lib\sinon\call.js:22:11)
at Object.yieldToOn (node_modules\sinon\lib\sinon\call.js:167:13)
at Object.yieldTo (node_modules\sinon\lib\sinon\call.js:156:31)
at Function.spyApi.(anonymous function) [as yieldTo] (node_modules\sinon\lib\sinon\spy.js:416:61)
at Context.it (test\controller\BookController.spec.js:47:17)
Am i doing it the right way? how do i return the callback result ?
bookController.js:
exports.getBook = (req, res) => {
//get from request
const id = req.params.id;
const params = [id];
bookDao.selectBook(params, function (result) {
res.status(200).json({
message: format(message.DEFAULT_MSG, "GET", constant.MODULE_URL),
result: result
});
});
};
bookDao.js:
function selectBook(params, callback) {
pool.open(connString, function (err, conn) {
conn.queryResult(query.SQL_SELECT, params, function (err, result) {
if (err) {
console.error(err);
return conn.closeSync();
}
var data = result.fetchAllSync();
// only when successful then call closeSync
result.closeSync();
return callback(data);
});
conn.close();
});
}
bookRest.js:
module.exports = (app) => {
// map to controller
const controller = require('../controller/bookController');
app.route(constant.MODULE_URL + '/:id').get(controller.getbook);
app.route(constant.MODULE_URL).put(controller.updateBooks);
};
bookController.spec.js:
process.env.NODE_ENV = 'test';
const sinon = require('sinon');
const chai = require('chai');
const chaiHttp = require('chai-http');
const should = chai.should();
const httpMocks = require('node-mocks-http');
let server = require('../../../main.js');
const bookController = require('../../../controller/bookController.js');
const bookDao = require('../../../dao/bookDao.js');
chai.use(chaiHttp);
let req = httpMocks.createRequest();
let res = httpMocks.createResponse();
describe('Book service', () => {
beforeEach(() => {
});
afterEach(() => {
});
it('1. should list a SINGLE Book /book/id GET', (done) => {
req.params.id = "XCV1234";
const selectbook = sinon.stub(bookDao, "selectbook");
bookController.getbook(req, res);
selectbook.yieldTo({BOOK_ID : "XCV1234"});
res.should.have.status(200);
res.should.be.json;
res.body.should.be.a('object');
res.body.result[0].should.include.keys(
'BOOK_ID'
);
sinon.restore();
done();
});
});
I'm afraid yieldsTo is not the appropriate method to use for this case. Based on documentation, this method is intended to target callback that passed as property as in
sinon.stub(jQuery, "ajax").yieldsTo("success", [1, 2, 3]);
jQuery.ajax({
success: function (data) {
assertEquals([1, 2, 3], data);
}
});
To solve your problem, we can use yields so it will be like:
...
// should be stubbed before `getbook` is called
sinon.stub(bookDao, "selectbook").yields({
BOOK_ID: "XCV1234"
});
bookController.getbook(req, res);
res.should.have.status(200);
...
Hope it helps
I've got 2 questions that I am searching for an answer for 3 days so far and can't figure it out.
1. When I should connect to the database when testing?
2. I always get an error when running the test: { "before each" hook for "should list all books on /book GET" } and haven't yet found a solution or the exact cause for it. What am I doing wrong? The only answer I have so far is not to call done() twice in beforeEach() but I ain't doing it...
var chai = require('chai'),
expect = chai.expect,
request = require('request'),
mongoose = require('mongoose'),
Book = require('./../models/book');
// book = require('../model')
mongoose.createConnection('mongodb://localhost/books');
describe('Testing the routes', () => {
beforeEach((done) => {
Book.remove({}, (err) => {
if (err) {
console.log(err);
}
});
var newBook = new Book();
newBook.title = "Lord Of The Rings";
newBook.author = "J. R. R. Tolkien";
newBook.pages = 1234;
newBook.year = 2000;
newBook.save((err) => {
if (err) {
console.log(err);
}
done();
});
});
it('should list all books on /book GET', (done) => {
var url = 'http://localhost:8080/book';
request.get(url, (error, response, body) => {
expect(body).to.be.an('array');
expect(body.length).to.equal(1);
done();
});
});
});
mongoose.createConnection is an asynchronous function. The function returns and Node.js continues on before the connection is actually established.
Mongoose returns promises for most asynchronous functions. Similar to using done, mocha supports waiting for promises to resolve/reject out of the box. As long as the promise is the return value to the mocha function.
describe('Testing the routes', function(){
before('connect', function(){
return mongoose.createConnection('mongodb://localhost/books')
})
beforeEach(function(){
return Book.remove({})
})
beforeEach(function(){
var newBook = new Book();
newBook.title = "Lord Of The Rings";
newBook.author = "J. R. R. Tolkien";
newBook.pages = 1234;
newBook.year = 2000;
return newBook.save();
});
it('should list all books on /book GET', function(done){
var url = 'http://localhost:8080/book';
request.get(url, (error, response, body) => {
if (error) done(error)
expect(body).to.be.an('array');
expect(body.length).to.equal(1);
done();
});
});
});
Also mocha makes use of this for configuration so avoid using arrow functions for the mocha definitions.
I have my source file for which i have written test cases for
var debug = require('debug')('kc-feed:source:fb');
var request = require('request');
var config = require('../../config').root;
exports.source = function fetchFeed (callback) {
var params = {
headers: {'content-type' : 'application/jsons'},
url: config.host + "v1/social/fb/sync_feed",
method: 'GET'
};
request(params, function(err, body, response) {
if(err) {
callback(err);
}
else {
var raw_data = JSON.parse(response);
callback(null, raw_data);
}
});
};
This is my mocha test case
var chai = require('chai'),
expect = chai.expect,
app = require('../app'),
rewire = require('rewire'),
fbfeed = rewire('../src/feed/source/fb_feed'),
supertest = require('supertest'),
sinon = require('sinon'),
nock = require('nock');
describe('test cases for fb feed file', function() {
var callback;
beforeEach(function(){
callback = sinon.spy();
});
after(function(){
nock.cleanAll();
});
it('callback should be called with the response', function(done) {
nock('http://localhost:3000/')
.get('/v1/social/fb/sync_feed')
.reply(200, {});
callback = sinon.spy();
fbfeed.source(callback);
sinon.assert.calledOnce(callback);
done();
});
it('callback should be called with the error', function(done) {
nock('http://localhost:3000/')
.get('/v1/social/fb/sync_feed')
.replyWithError(new Error('err'));
fbfeed.source(callback);
sinon.assert.calledOnce(callback);
done();
});
Both my test cases fail as it says that callback is called 0 times. But the callback is always called. Please help.
It looks like the requests are still being performed asynchronously (I can't definitively say if this is expected when using nock), so you can't use spies like that.
Provide a regular callback instead:
fbfeed.source(function(err, raw_data) {
...make your assertions...
done();
});
I ran into an issue today where I had passing tests that should have failed. There were some incorrectly stubbed methods using Sinon that failed to stub out the callback correctly. I would have expected execution to fail, but it passed the test, however it stopped execution early because my test messages quit logging to the console at the incorrectly stubbed method invocation.
The code I had was similar to the following:
exports.myFunc = function (req, res) {
var innerFunc = function(callback) {
fs.exists('some/dir', function (exists) {
if (!exists) { // handle error }
else {
logger.log('this prints to the console');
utilModule.stubbedMethod('some/dir', callback);
}
});
};
logger.log('this also prints to the console');
innerFunc(function (err, value) {
logger.log('this does not print to the console');
if (err) {
logger.log('this does not print to the console');
res.status(500).send(err);
} else {
logger.log('this does not print to the console, either');
res.send('success');
}
});
});
// This is the tests, now:
var app = require('../app'),
mod = require('../lib/myModule'),
request = require('supertest'),
chai = require('chai'),
sinon = require('sinon');
describe('For module myModule', function () {
...
describe('#myFunc', function () {
var fs = require('fs'),
util = require('../lib/utilModule');
describe('Happy path', function () {
var expectedResult = "expected";
before(function() {
sinon.stub(fs, 'exists').yields(true, null);
sinon.stub(mod, 'stubbedMethod').yield("some value");
// the above is wrong and should have been yield(null, null, "some value")
});
after(function () { fs.exists.restore(); mod.stubbedMethod.restore(); });
it('Replies with the right value and status 200', function () {
request(app).get('/url').expect(200, 'success').end(function(err, res) {
if (err) throw err;
}
});
});
});
Why did this test pass, and is there some way to prevent it from passing?