The statement is a violation of the asynchronous function in the Mocha test

I create a node module and try my best to extract unit test from it. I installed mocha and chai to handle the test. I had a problem testing my asynchronous methods (methods returning promises).

In the next test, I test the method of the Update object.

it('Should return a list of versions for the default git repo', function (done) { fs.writeFileSync(appSetup.CONFIG_FILENAME, JSON.stringify(appSetup.DEFAULT_CONFIG)); var upgrade = new Upgrade({ quiet: true }); upgrade.getVersions().then(function (versions) { assert(versions && versions.length > 0, 'Should have at least one version.'); assert.equal(1, 2); // this throws the exception which causes the test case not even exist done(); }, done); }); 

The getVersions() call returns a promise as an async method. When the promise is resolved, I want to check the value returned in the versions variable.

assert(versions && versions.length > 0, 'Should have at least one version.'); - the actual test. I added assert.equal(1, 2); , because I noticed that when the test fails, the test case will not even appear in the test list.

I assume that calling assert throws an exception that Mocha should catch. However, it falls into the function of the promises then handler.

What's going on here? Why, when the statement fails in this method, does the test case not display in the list (it does not display as a failure, as it does not exist)?

+6
source share
2 answers

The core of the problem is that the code you have is essentially:

 try { var versions = upgrade.getVersions(); } catch (err){ return done(err); } assert(versions && versions.length > 0, 'Should have at least one version.'); assert.equal(1, 2); // this throws the exception which causes the test case not even exist done(); 

Looking at this, it should be clear that if these statements are thrown away, then the callback will not be executed.

 try { var versions = upgrade.getVersions(); assert(versions && versions.length > 0, 'Should have at least one version.'); assert.equal(1, 2); // this throws the exception which causes the test case not even exist done(); } catch (err){ return done(err); } 

looks more like what you want:

 upgrade.getVersions().then(function (versions) { assert(versions && versions.length > 0, 'Should have at least one version.'); assert.equal(1, 2); // this throws the exception which causes the test case not even exist }).then(done, done); 

Node to have this execute statements and then move the callbacks to a secondary .then() , which will always handle errors.

However, it would be much easier to simply return the promise as

 return upgrade.getVersions().then(function (versions) { assert(versions && versions.length > 0, 'Should have at least one version.'); assert.equal(1, 2); // this throws the exception which causes the test case not even exist }); 

so that Mocha controls the promise itself without a callback.

+11
source

The test does not appear in the list until you call a callback that will never happen if this statement fails. You will need to call .catch(done) in the final promise to ensure that done always invoked.

The test will appear if you give it a timeout value, which you probably should do.

All that said, mocha understands promises. You don't have to deal with callbacks at all:

  it('Should return a list of versions for the default git repo', function () { fs.writeFileSync(appSetup.CONFIG_FILENAME, JSON.stringify(appSetup.DEFAULT_CONFIG)); var upgrade = new Upgrade({ quiet: true }); return upgrade.getVersions().then(function (versions) { assert(versions && versions.length > 0, 'Should have at least one version.'); assert.equal(1, 2); }); }); 
+4
source

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


All Articles