I am learning node.js and how to test functions. I have a problem when using mocha: when functions are passing test, everything is completely fine, I get a nice looking message.
But if whichever function which doesnt pass a test - for example the result in the test is 0 but intentionally I wrote the asswertion to expect 1 - it gives me a mile long error massage in the bash-cli-console:
Async functions
(node:6001) UnhandledPromiseRejectionWarning: AssertionError [ERR_ASSERTION]: 0 == 1
at utils.requestWikiPage.then.resBody (/home/sandor/Documents/learning-curve-master/node-dev-course/testing-tut/utils/utils.test.js:10:20)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:188:7)
(node:6001) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:6001) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
1) it should return a html page
0 passing (2s)
1 failing
1) Async functions
it should return a html page:
Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves. (/home/sandor/Documents/learning-curve-master/node-dev-course/testing-tut/utils/utils.test.js)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! dev-course#1.0.0 test: `mocha ./testing-tut/**/*.test.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the dev-course#1.0.0 test script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! /home/sandor/.npm/_logs/2018-07-04T11_31_53_292Z-debug.log
[nodemon] app crashed - waiting for file changes before starting...
I dont know why do I get this part: UnhandledPromiseRejectionWarning...
and why do I get this part: npm ERR! code ELIFECYCLE
the function I am testing: (it makes a request to wikipedia for the wiki page of george washington and collects the html page from the response. On 'end' of the responses readstream it resolves the html page. The function works just fine)
// utils.js
function requestWikiPage() {
const reqOpts = {
hostname : 'en.wikipedia.org',
port : 443,
path : '/wiki/George_Washington',
method : "GET"
}
return new Promise(resolve => {
let req = https.request(reqOpts, (res) => {
let resBody = "";
res.setEncoding('utf-8');
res.on('data', (chunk) => {
resBody += chunk;
});
res.on('end', () => {
resolve(resBody);
});
});
req.on('err', (err) => {
console.log(err);
});
req.end();
});
}
module.exports.requestWikiPage = requestWikiPage;
Mocha code: (The 'resBody' variable is a string, containing a html page, where '' stays on the index of 0. In the assertion I test it for 1 to create an error message)
const utils = require('./utils');
var assert = require('assert');
describe('Async functions', function() {
it('it should return a html page', (done) => {
utils.requestWikiPage().then(resBody => {
assert.equal(resBody.indexOf('<!DOCTYPE html>'), 1);
done();
});
});
});
So I dont understand why do I get that long error message just because I expect to be not on the 0 index than on the first? (Actually I get that error message whith every function not just with this)
How can I set up mocha that it gives me a more minimal and intuitive error message.
Thanks a million for your answers
You need to properly reject the promise in #requestWikiPage if it doesn't resolve or there is an error, and then handle that rejection in your test. The following changes will likely solve the issue in your question (i.e. having mocha correctly handle a failed test without all the extra output), but the next step would obviously be getting your test to pass.
Notice we add the reject callback to our new Promise() and instead of console.log(err); below in your req.on('error'... callback, we now use reject as our error callback.
// utils.js
function requestWikiPage() {
const reqOpts = {
hostname : 'en.wikipedia.org',
port : 443,
path : '/wiki/George_Washington',
method : "GET"
}
return new Promise((resolve, reject) => {
let req = https.request(reqOpts, (res) => {
let resBody = "";
res.setEncoding('utf-8');
res.on('data', (chunk) => {
resBody += chunk;
});
res.on('end', () => {
resolve(resBody);
});
});
req.on('err', reject);
req.end();
});
}
module.exports.requestWikiPage = requestWikiPage;
And now handle if the promise is rejected via a catch block by using done as the catch callback (which would effectively pass the error to done which mocha requires).
const utils = require('./utils');
var assert = require('assert');
describe('Async functions', function() {
it('it should return a html page', (done) => {
utils.requestWikiPage().then(resBody => {
assert.equal(resBody.indexOf('<!DOCTYPE html>'), 1);
done();
}).catch(done);
});
});
Related
This might be a case of 'you're using the wrong tools for the job' but I'm going to shoot my question anyways, because this is what I have to work with for now.
So, here goes:
I have to make relatively small applications that periodically run as functions in an Azure environment. These applications perform tasks like fetching data from an API and storing that data on a SFTP server. When I create these applications I use a TDD approach with Jest.
I'd like to react to any problems proactively and solve them before the function runs are scheduled. If I run Jest locally I would notice any of these problems but I'd like to automate this proces. Therefor I'd like to know if it's possible to run these tests from an Azure function and have Azure Warnings notify me when one these runs fail.
What have I tried?
Created new function folder "Jest_Function"
Added an always failing test in a separate file.
/main_functions_folder
/jest_function
- index.js
- function.json
- failingTest.test.js
added the following code to index.js:
const { exec } = require('child_process');
function checkTests() {
return new Promise((resolve, reject) => {
exec('npm run test failingTest.test.js', (error) => {
if (error) reject(error);
else resolve();
});
});
}
module.exports = async function (context) {
try {
await checkTests();
} catch (err) {
context.log('tests failed!');
throw err;
}
};
Transforming the function and running it in the terminal results in expected behaviour:
const { exec } = require('child_process');
function checkTests() {
return new Promise((resolve, reject) => {
exec('npm run test failingTest.test.js', (error) => {
if (error) reject(error);
else resolve();
});
});
}
async function myTest() {
try {
await checkTests();
} catch (err) {
console.log('tests failed!');
throw err;
}
}
myTest();
tests failed!
node:child_process:399
ex = new Error('Command failed: ' + cmd + '\n' + stderr);
^
Error: Command failed: npm run test failingTest.test.js
FAIL jest_function/failingTest.test.js
✕ short test (3 ms)
● short test
expect(received).toBe(expected) // Object.is equality
Expected: 1
Received: 0
1 | test('short test', () => {
> 2 | expect(0).toBe(1);
| ^
3 | });
4 |
at Object.<anonymous> (jest_function/failingTest.test.js:2:13)
Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
Snapshots: 0 total
Time: 0.227 s, estimated 1 s
Ran all test suites matching /failingTest.test.js/i.
at ChildProcess.exithandler (node:child_process:399:12)
at ChildProcess.emit (node:events:520:28)
at maybeClose (node:internal/child_process:1092:16)
at Process.ChildProcess._handle.onexit (node:internal/child_process:302:5) {
killed: false,
code: 1,
signal: null,
cmd: 'npm run test failingTest.test.js'
}
Azure
I deployed the function in Azure and manualy ran it. This resulted in a failing function as I expected, but for the wrong reason. It displayed the following error message:
Result: Failure Exception: Error: Command failed: npm run test failingTest.test.js sh: 1: jest: Permission denied
I'm not really sure where to go from here, any help or advice will be appreciated!
Not sure if you can use jest directly from within Functions but I know you can run pupeteer headless in Azure Functions:
https://anthonychu.ca/post/azure-functions-headless-chromium-puppeteer-playwright/
and there's also jest-pupeteer package but not sure if there is a specific limitation on jest in Functions if all of the deps are installed as runtime dependencies.
I was able to make this work using npx instead of npm:
const { exec } = require('child_process');
function checkTests() {
return new Promise((resolve, reject) => {
exec('npx jest jest_function/failingTest.test.js', (error) => {
if (error) reject(error);
else resolve();
});
});
}
module.exports = async function (context) {
try {
await checkTests();
} catch (err) {
context.log('tests failed!');
throw err;
}
};
Looking at the logs I'm not really sure what '330' exactly is, but is assume it is installing jest?
2022-04-19T09:54:06Z [Information] Error: Command failed: npx jest
npx: installed 330 in 32.481s
Anyways I'm glad I got this working now :).
I'm trying to use Contentful, a new JS library for building static websites. I want to use it in Node JS.
I created an app file like this (the name is getContent.js):
'use strict';
var contentful = require('contentful')
var client = contentful.createClient({
space: '****',
accessToken: '****'
});
module.exports = client;
function getEntry() {
return client.getEntry('******')
.then(function (entry) {
// logs the entry metadata
console.log(entry.sys)
// logs the field with ID title
console.log(entry.fields.channelName)
})
}
Then I created a test (getContent.test.js) like this:
'use strict';
let chai = require('chai');
let should = chai.should();
var expect = chai.expect;
var rewire = require("rewire");
let getContent = rewire("./getContent.js");
describe('Retreive existing', () => {
it('it should succeed', (done) => {
getContent.getEntry({contentName:'****'
}, undefined, (err, result) => {
try {
expect(err).to.not.exist;
expect(result).to.exist;
// res.body.sould be equal
done();
} catch (error) {
done(error);
}
});
});
});
but I obtain this error:
Retreive existing (node:42572) UnhandledPromiseRejectionWarning:
Error: Request failed with status code 400
at createError (/Users/ire/Projects/SZDEMUX_GDPR/api/node_modules/contentful/dist/contentful.node.js:886:15)
at settle (/Users/ire/Projects/SZDEMUX_GDPR/api/node_modules/contentful/dist/contentful.node.js:1049:12)
at IncomingMessage.handleStreamEnd (/Users/ire/Projects/SZDEMUX_GDPR/api/node_modules/contentful/dist/contentful.node.js:294:11)
at emitNone (events.js:111:20)
at IncomingMessage.emit (events.js:208:7)
at endReadableNT (_stream_readable.js:1064:12)
at _combinedTickCallback (internal/process/next_tick.js:138:11)
at process._tickCallback (internal/process/next_tick.js:180:9) (node:42572) UnhandledPromiseRejectionWarning: Unhandled promise
rejection. This error originated either by throwing inside of an async
function without a catch block, or by rejecting a promise which was
not handled with .catch(). (rejection id: 3) (node:42572) [DEP0018]
DeprecationWarning: Unhandled promise rejections are deprecated. In
the future, promise rejections that are not handled will terminate the
Node.js process with a non-zero exit code.
Do you know what I'm missing? the promise is ok, I already tested it with a simple node getContent.js
I am seeing few issues with your code:
1. Invalid Args
In your test function, in getContent.js, you are passing an argument to the getEntry method (return client.getEntry('******'), whereas you are passing an object in the test (getContent.getEntry({}))
2. Mixing Promises & Callbacks
it('it should succeed', (done) => {
getContent.getEntry("****")
.then((result) => {
console.log(result);
try {
expect(result).to.exist;
// res.body.sould be equal
done();
} catch (error) {
done(error);
}
})
.catch(error => {
console.log(error);
done(error)
})
});
3. Source of Unhandled Promise rejection is not clear:
Is it coming from your test function in getContent.js, or, is it coming from your actual test?
Probably, this could also come from,
expect(err).to.not.exist;
expect(result).to.exist;
Always catch errors in Promises and reject it with proper reason to avoid issues like this.
Could you please update your code and repost it, so that its clear for other users?
I want to connect to the tarantool cotainer using this code:
import TarantoolConnection from 'tarantool-driver'
let connection = new TarantoolConnection('192.168.99.100:3301');
connection.ping().then((res) => {
console.log(res);
});
Before that i started container:
docker run -p 3301:3301 -d tarantool/tarantool:1.6
But in result i get nothing.
If i try to create space or\and index for this space:
connection.eval("box.schema.space.create('myspace', {if_not_exists=true, temporary=true})").then((res) => {
console.log(res);
});
I get this error:
UnhandledPromiseRejectionWarning: Unhandled promise
rejection (rejection id: 1): Error: This socket is closed
or:
UnhandledPromiseRejectionWarning: Unhandled promise
rejection (rejection id: 2): Error: connection will be destroyed or
already destroyed, create another one
As i see from the error, the needed socket is already closed, but i don't understand why.
Version of tarantool driver:
"tarantool-driver": "2.0.5",
How can i fix it?
You have two problems here:
You should connect to localhost:3301 instead of 192.168.99.100:3301
You have to use connection.connect() before connection.ping() or connection.eval()
Here is the working code:
const TarantoolConnection = require('tarantool-driver');
let connection = new TarantoolConnection({port: 3301});
connection.connect().then((res) => {
console.log("Connected: " + res);
connection.ping().then((res) => {
console.log("Pong: " + res);
});
connection.eval("box.schema.space.create('myspace', {if_not_exists=true, temporary=true})").then((res) => {
console.log("Space created");
});
});
Just in case, I've used the following command to start tarantool docker instance:
$ docker run --rm -p 3301:3301 -t -i tarantool/tarantool:1.6
I'm pretty new to coding and to Node.JS but trying to learn... The first big difficulties I found with Node.JS was to think in an Async way when building your code, now I'm facing another monster: Promises.
Up until now, I've tried to build my code to get something to work and not minding at all the error handling (I know that's dumb, but it helps me learn) but now while running my code I get some errors from time to time.
Since "my program" is basically (for now) a bunch of requests (using request-promise) being made through infinite loops. Some manipulation of the info ({objects}) being received and sending it to a mongodb (via mongoose), I mostly know where the errors are coming from:
The servers (being requested) are returning an error (statusCode !== 200).
Too many requests were made (which is obviously a specific statusCode)
And my code runs mostly smoothly, until I get one of these errors. My objective is now to get back into the code to handle properly these errors and create logs once they occur. Another ideal function would be to restart the loop that yielded the error (request) once they occur (maybe after a setTimeout or something).
My questions are:
Could you recommend some great material on promiseRejection handling that I could dig into? For now I'm using .catch((err) => { foo }) for each promise, but I'm not sure what to do with the err once caught.
Is there out there something that helps with logs and promiseRejection handling (an npm package maybe)?
How can I handle a loop restart? Again, I'm not expecting for you to provide a full response with the whole code (if you can that's obviously even better) but to put me in the right direction (best practices, famous npms or articles to achieve this)!
I really hope I'm not out of the topic and following SO's rule! If not let me know and I'll delete the question or edit and adapt.
Thanks in advance for your help!
******* EDIT ********
Simplifying my code:
[]./module/apiRequest.js[]
var rq = require('request-promise');
var fs = require('fs');
function apiRequest(params, req) {
var date = new Date().toISOString();
var logFileName = '../logs/[KRAKEN]'+date+'errorlog.txt';
var options = {
uri: `https://api.kraken.com/0/public/${params}`,
qs: req,
json: true,
resolveWithFullResponse: true
};
return rq(options).then((res) => {
if (res.statusCode === 200 && !res.body.error.length) {
return res; // <=== THIS FOR AN UNKNOWN PARAM, THIS SERVER RETURNS A 200 WITH AN ERROR OBJECT.
} else {
fs.writeFile(logFileName, res, function(err) {
if (err) return console.log(err); // <==== SINCE A 200 WON'T APPEAR AS AN ERROR I'M TRYING TO HANDLE IT THAT WAY.
console.log(`[ERROR][KRAKEN]: log created!`);
});
}
}).catch((err) => { // <==== AS FAR AS I UNDERSTAND THIS IS FOR ANY OTHER ERROR (STATUSCODE 500 FOR INSTANCE / OR AN ERROR RELATED WITH THE CODE)
fs.writeFile(logFileName, err, function(err) {
if (err) return console.log(err);
console.log(`[ERROR][KRAKEN]: log created!`);
});
});
};
module.exports = {
apiRequest
};
[]./module/app.js[]
var apiRequest = require('./apiRequest.js').apiRequest;
function kraken(item) {
return apiRequest('Ticker', {pair: item}).then((res) => {
var result = {};
var timeStamp = Math.floor(new Date());
Object.keys(res.body.result).forEach((k) => {
result= {
mk: 'kraken',
name: k,
a: res.body.result[k].a,
b: res.body.result[k].b,
c: res.body.result[k].c,
v: res.body.result[k].v,
p: res.body.result[k].p,
t: res.body.result[k].t,
l: res.body.result[k].l,
h: res.body.result[k].h,
o: res.body.result[k].o,
n: timeStamp,
}
});
return result; // <=== THIS OCCURS WHEN THERE'S NO ERROR IN THE APIREQUEST.
}).catch((err) => {
console.log(err); // <==== THIS I'M NOT SURE IF IT GETS THE ERROR BACK FROM APIREQUEST. IF I'M NOT MISTAKEN THAT'S NOT THE CASE, IT'S THE ERROR HANDLER FOR THE 'kraken' FUNCTION I'M NOT SURE WHAT KIND OF ERRORS COULD COME OUT OF THIS...
});
};
module.exports = {
kraken,
}
[]./main.js[]
var fs = require('fs');
var mongo = require('mongodb');
var mongoose = require('mongoose');
mongoose.Promise = global.Promise;
// KRAKEN REQUIRE:
var kraken = require('./module/app.js').kraken;
var Krakentick = require('./module/model/krakenModel').Krakentick; //<=== THIS IS THE MODEL FOR MONGOOSE.
async function loopKR() {
setTimeout(
async function () {
var item = ['XBTUSD'];
var data = await kraken(item);
data.forEach((object) => {
if (object.name === 'XXBTZUSD') {
var iname = 'btcusd'
} else {
var iname = 'N/A' };
var tick = new Krakentick({
mk: object.mk,
name: object.name,
a: object.a,
b: object.b,
c: object.c,
v: object.v,
p: object.p,
t: object.t,
l: object.l,
h: object.h,
o: object.o,
n: object.n,
iname: iname,
});
tick.save(function(err, tick) {
if (err) return console.log(err); //<==== THIS IS RELATED WITH MONGOOSE NOT A PROMISE IF I'M NOT MISTAKEN... THEN HANDLING WOULD OCCUR IF I HAD A PROBLEM
console.log(`[SUCCESS][KRAKEN]: ${tick.name} added to db!`);
});
});
loopKR();
}
}, 1100);
};
loopKR();
So as you can see, I'm trying to handle mainly the errors coming out of the request. But how do I send them to a log (is my current code correct? Is there a better way?)? And after the error arises and breaks the loop, how do I restart the loop automatically?
With this code, the errors are not being handled properly... For some reasons I get the following message:
TypeError: Cannot read property 'body' of undefined
at apiRequest.then (fast-crypto/module/app.js:34:22)
at tryCatcher (fast-crypto/node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (fast-crypto/node_modules/bluebird/js/release/promise.js:512:31)
at Promise._settlePromise (fast-crypto/node_modules/bluebird/js/release/promise.js:569:18)
at Promise._settlePromise0 (fast-crypto/node_modules/bluebird/js/release/promise.js:614:10)
at Promise._settlePromises (fast-crypto/node_modules/bluebird/js/release/promise.js:693:18)
at Async._drainQueue (fast-crypto/node_modules/bluebird/js/release/async.js:133:16)
at Async._drainQueues (fast-crypto/node_modules/bluebird/js/release/async.js:143:10)
at Immediate.Async.drainQueues (fast-crypto/node_modules/bluebird/js/release/async.js:17:14)
at runCallback (timers.js:781:20)
at tryOnImmediate (timers.js:743:5)
at processImmediate [as _immediateCallback] (timers.js:714:5) (node:12507) UnhandledPromiseRejectionWarning: Unhandled promise
rejection (rejection id: 1): TypeError: Cannot read property 'name' of
undefined (node:12507) [DEP0018] DeprecationWarning: Unhandled promise
rejections are deprecated. In the future, promise rejections that are
not handled will terminate the Node.js process with a non-zero exit
code. { Error: ENOENT: no such file or directory, open
'../logs/[KRAKEN]2017-08-20T10:58:03.302Zerrorlog.txt' errno: -2,
code: 'ENOENT', syscall: 'open', path:
'../logs/[KRAKEN]2017-08-20T10:58:03.302Zerrorlog.txt' }
So, I'm testing a component that relies on an event-emitter. To do so I came up with a solution using Promises with Mocha+Chai:
it('should transition with the correct event', (done) => {
const cFSM = new CharacterFSM({}, emitter, transitions);
let timeout = null;
let resolved = false;
new Promise((resolve, reject) => {
emitter.once('action', resolve);
emitter.emit('done', {});
timeout = setTimeout(() => {
if (!resolved) {
reject('Timedout!');
}
clearTimeout(timeout);
}, 100);
}).then((state) => {
resolved = true;
assert(state.action === 'DONE', 'should change state');
done();
}).catch((error) => {
assert.isNotOk(error,'Promise error');
done();
});
});
On the console I'm getting an 'UnhandledPromiseRejectionWarning' even though the reject function is getting called since it instantly shows the message 'AssertionError: Promise error'
(node:25754) UnhandledPromiseRejectionWarning: Unhandled promise
rejection (rejection id: 2): AssertionError: Promise error: expected
{ Object (message, showDiff, ...) } to be falsy
should transition with the correct event
And then, after 2 sec I get
Error: timeout of 2000ms exceeded. Ensure the done() callback is
being called in this test.
Which is even weirder since the catch callback was executed(I think that for some reason the assert failure prevented the rest of the execution)
Now the funny thing, if I comment out the assert.isNotOk(error...) the test runs fine without any warning in the console. It stills 'fails' in the sense that it executes the catch.
But still, I can't understand these errors with promise. Can someone enlighten me?
The issue is caused by this:
.catch((error) => {
assert.isNotOk(error,'Promise error');
done();
});
If the assertion fails, it will throw an error. This error will cause done() never to get called, because the code errored out before it. That's what causes the timeout.
The "Unhandled promise rejection" is also caused by the failed assertion, because if an error is thrown in a catch() handler, and there isn't a subsequent catch() handler, the error will get swallowed (as explained in this article). The UnhandledPromiseRejectionWarning warning is alerting you to this fact.
In general, if you want to test promise-based code in Mocha, you should rely on the fact that Mocha itself can handle promises already. You shouldn't use done(), but instead, return a promise from your test. Mocha will then catch any errors itself.
Like this:
it('should transition with the correct event', () => {
...
return new Promise((resolve, reject) => {
...
}).then((state) => {
assert(state.action === 'DONE', 'should change state');
})
.catch((error) => {
assert.isNotOk(error,'Promise error');
});
});
For those who are looking for the error/warning UnhandledPromiseRejectionWarning outside of a testing environment, It could be probably because nobody in the code is taking care of the eventual error in a promise:
For instance, this code will show the warning reported in this question:
new Promise((resolve, reject) => {
return reject('Error reason!');
});
(node:XXXX) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: Error reason!
and adding the .catch() or handling the error should solve the warning/error
new Promise((resolve, reject) => {
return reject('Error reason!');
}).catch(() => { /* do whatever you want here */ });
Or using the second parameter in the then function
new Promise((resolve, reject) => {
return reject('Error reason!');
}).then(null, () => { /* do whatever you want here */ });
I got this error when stubbing with sinon.
The fix is to use npm package sinon-as-promised when resolving or rejecting promises with stubs.
Instead of ...
sinon.stub(Database, 'connect').returns(Promise.reject( Error('oops') ))
Use ...
require('sinon-as-promised');
sinon.stub(Database, 'connect').rejects(Error('oops'));
There is also a resolves method (note the s on the end).
See http://clarkdave.net/2016/09/node-v6-6-and-asynchronously-handled-promise-rejections
The assertion libraries in Mocha work by throwing an error if the assertion was not correct. Throwing an error results in a rejected promise, even when thrown in the executor function provided to the catch method.
.catch((error) => {
assert.isNotOk(error,'Promise error');
done();
});
In the above code the error objected evaluates to true so the assertion library throws an error... which is never caught. As a result of the error the done method is never called. Mocha's done callback accepts these errors, so you can simply end all promise chains in Mocha with .then(done,done). This ensures that the done method is always called and the error would be reported the same way as when Mocha catches the assertion's error in synchronous code.
it('should transition with the correct event', (done) => {
const cFSM = new CharacterFSM({}, emitter, transitions);
let timeout = null;
let resolved = false;
new Promise((resolve, reject) => {
emitter.once('action', resolve);
emitter.emit('done', {});
timeout = setTimeout(() => {
if (!resolved) {
reject('Timedout!');
}
clearTimeout(timeout);
}, 100);
}).then(((state) => {
resolved = true;
assert(state.action === 'DONE', 'should change state');
})).then(done,done);
});
I give credit to this article for the idea of using .then(done,done) when testing promises in Mocha.
I faced this issue:
(node:1131004) UnhandledPromiseRejectionWarning: Unhandled promise rejection (re
jection id: 1): TypeError: res.json is not a function
(node:1131004) DeprecationWarning: Unhandled promise rejections are deprecated.
In the future, promise rejections that are not handled will terminate the Node.j
s process with a non-zero exit code.
It was my mistake, I was replacing res object in then(function(res), so changed res to result and now it is working.
Wrong
module.exports.update = function(req, res){
return Services.User.update(req.body)
.then(function(res){//issue was here, res overwrite
return res.json(res);
}, function(error){
return res.json({error:error.message});
}).catch(function () {
console.log("Promise Rejected");
});
Correction
module.exports.update = function(req, res){
return Services.User.update(req.body)
.then(function(result){//res replaced with result
return res.json(result);
}, function(error){
return res.json({error:error.message});
}).catch(function () {
console.log("Promise Rejected");
});
Service code:
function update(data){
var id = new require('mongodb').ObjectID(data._id);
userData = {
name:data.name,
email:data.email,
phone: data.phone
};
return collection.findAndModify(
{_id:id}, // query
[['_id','asc']], // sort order
{$set: userData}, // replacement
{ "new": true }
).then(function(doc) {
if(!doc)
throw new Error('Record not updated.');
return doc.value;
});
}
module.exports = {
update:update
}
Here's my take experience with E7 async/await:
In case you have an async helperFunction() called from your test... (one explicilty with the ES7 async keyword, I mean)
→ make sure, you call that as await helperFunction(whateverParams) (well, yeah, naturally, once you know...)
And for that to work (to avoid ‘await is a reserved word’), your test-function must have an outer async marker:
it('my test', async () => { ...
I had a similar experience with Chai-Webdriver for Selenium.
I added await to the assertion and it fixed the issue:
Example using Cucumberjs:
Then(/I see heading with the text of Tasks/, async function() {
await chai.expect('h1').dom.to.contain.text('Tasks');
});
Just a heads-up that you can get a UnhandledPromiseRejectionWarning if you accidentally put your test code outside of the it-function. 😬
describe('My Test', () => {
context('My Context', () => {
it('should test something', () => {})
const result = testSomething()
assert.isOk(result)
})
})