Synchronous code testing

I have a section of code that uses node-sync like this:

function funcA() { return new Promise(function(resolve, reject) { Sync(function () { return funcB.sync(); }, function (err, result) { if(err) { reject(err); } else { resolve(result); } }); } 

This code is checked using mocha + chai:

 it("should return array", function() { return funcA().then(function(result) { expect(result).to.be.an.instanceof(Array); }); }); 

It worked wonderfully a couple of months ago, but now this test always expires:

Error: Exceeded 2000 ms. Verify that the done () callback is called in this test.

What I have tried so far:

  • using done() instead of returning a promise
  • replacing node-sync with synchronize.js
  • timeout increase

What I found out is that part of this test expect(... , in fact, called, but only after the mocha kills the test. No matter what timeout interval is set, expect(.. is called always ~ 20 milliseconds after receiving the Error: timeout message.

I fixed the problem by adding setInterval(function(){}, 10) to the beginning of the test file. I would like to know why this worked, and if there is a better way to fix this?

[EDIT] This seems to be a problem with the node version. The test fails with error 0.12.4, but works correctly on 0.10.38.

[EDIT] The actual code is available here .

+6
source share
3 answers

Based on your code , I assume that your funcB function works with the code synchronously .

So, when I create funcB this way:

 function funcB() { return [1, 2, 3]; } 

And run the test, Mocha shows an error:

Error: Exceeded 2000 ms. Verify that the done () callback is called in this test.

But if I convert funcB to an asynchronous function like this:

 function funcB(cb) { process.nextTick(function () { cb(null, [1, 2, 3]); }); } 

Mocha runs the test without problems:

βœ“ should return an array


So, my complete code that works fine (comment funcB is the one that will throw the error):

 // install dependencies // npm install promise // npm install sync var Promise = require('promise'); var assert = require('assert'); var Sync = require('sync'); function funcA() { return new Promise(function (resolve, reject) { Sync(function () { return funcB.sync(); }, function (err, result) { if (err) { reject(err); } else { resolve(result); } }); }); } // function funcB() { // return [1, 2, 3]; // } function funcB(cb) { process.nextTick(function () { cb(null, [1, 2, 3]); }); } it("should return an array", function(done) { return funcA().then( function (result) { console.log(result); assert.equal(Array.isArray(result), true); done(); } ); }); 

So, I believe that the misuse of the synchronization method (using it on synchronous functions) created by the synchronization library is the one that causes this problem.

+2
source

Perhaps you just miss the done() callback:

 it("should return array", function(done) { funcA().then(function(result) { expect(result).to.be.an.instanceof(Array); done(); }); }); 

http://mochajs.org/#asynchronous-code

+1
source

You can use the timeout parameter for the mocha executable.

For example, if you want a timeout of 500 milliseconds, just change your package.json to:

 "scripts": { "test": "mocha specs --timeout 500 --require specs/helpers/chai.js" }, 

And perhaps your promise is rejected, so you need to call done with the catch method.

 it("should return array", function(done) { return funcA().then(function(result) { expect(result).to.be.an.instanceof(Array); done(); }).catch(done); }); 

It will also help you debug possible errors that might occur in your promise code.

+1
source

Source: https://habr.com/ru/post/988618/


All Articles