Node.js – 摩卡done()方法在以前的testing中导致错误

我正在实现摩卡作为我的testing框架与柴我为Node.js写一个应用程序。 这个规范是为secureId.js写的。

 // secureId.js "use strict" const bcrypt = require('bcrypt'); // Constructor for SecureID function SecureID(str, rounds, func) { // Makes salt and hash unable to be changed or viewed outside the member functions let hashedID; let gennedSalt; bcrypt.genSalt(rounds, (err, salt) => { gennedSalt = salt; bcrypt.hash(str, salt, (err, hash) => { hashedID = hash; func(err, salt, hash); }); }); // Gets the salt associated with the instance this.getSalt = function() { return gennedSalt; }; // Gets the hash associated with the instance this.getHash = function() { return hashedID; }; // Set new id for already instantiated SecureID this.setNewId = function(str, rounds, func) { bcrypt.genSalt(rounds, function(err, salt) { gennedSalt = salt; if (err) func(err); bcrypt.hash(str, salt, function(err, hash) { hashedID = hash; func(err, salt, hash); }); }); }; // set new id for already instantiated SecureID synchronously this.setNewIdSync = function(str, rounds) { gennedSalt = bcrypt.genSaltSync(rounds); hashedID = bcrypt.hashSync(str, gennedSalt); }; // Compares a string and hash this.equals = function(str, func) { bcrypt.compare(str, hashedID, function(err, res) { func(err, res); }); }; // Compares a string and hash synchronously this.equalsSync = function(str) { return bcrypt.compareSync(str, hashedID); }; }; exports.SecureID = SecureID; 

这是规范。

 "use strict"; let expect = require('chai').expect; describe('SecureID', () => { let ids = []; let anID = 'aLongIDofCharacters'; let anAmountOfRounds = 10; let SecureID = require('../secureId').SecureID; console.log(`Tests with rounds >= 20 will take over an hour to complete. You are doing ${anAmountOfRounds} round(s).`); describe('#SecureID()', () => { let i = 0; let checkingFunction = (done) => { if (i == 2) { clearInterval(checkingFunction); done(); }; }; it('Create an ID', (done) => { for (let j = 0; j <= 1; j++) { ids.push(new SecureID(anID, anAmountOfRounds, (err, salt, hash) => { expect(err).to.be.undefined; expect(salt).not.to.be.undefined; expect(hash).not.to.be.undefined; i++; })); }; setInterval(checkingFunction, 100, done); }); }); describe('#getHash()', () => { it('Returns a hash.', () => { expect(ids[0].getHash()).not.to.be.undefined; expect(ids[1].getHash()).not.to.be.undefined; }); it('Returns a hash unique to that generated from the same ID.', () => { expect(ids[0].getHash()).not.to.equal(ids[1].getHash()); }); }); describe('#getSalt()', () => { it('Returns a salt.', () => { expect(ids[0].getSalt()).not.to.be.undefined; expect(ids[1].getSalt()).not.to.be.undefined; }); it('Returns a salt unique to that generated from the same ID.', () => { expect(ids[1].getSalt()).not.to.equal(ids[0].getSalt()); }); }); describe('#setNewId()', () => { let i = 0; let checkingFunction = (done) => { if (i == 2) { clearInterval(checkingFunction); done(); }; }; it('Sets a new ID asynchronously.', (done) => { for (let j = 0; j <= 1; j++) { ids[j].setNewId(anID, (err, salt, hash) => { let previousHash = ids[j].getHash(); let previousSalt = ids[j].getSalt(); expect(err).to.be.undefined; expect(salt).not.to.equal(previousSalt); expect(hash).not.to.equal(previousHash); i++; }); }; setInterval(checkingFunction, 100, done); }); }); describe('#setNewIdSync()', () => { it('Sets a new ID synchronously.', () => { for (let j = 0; j <= 1; j++) { let previousHash = ids[j].getHash(); let previousSalt = ids[j].getSalt(); ids[j].setNewIdSync(anID); expect(ids[j].getSalt()).not.to.equal(previousSalt); expect(ids[j].getHash()).not.to.equal(previousHash); }; }); }); describe('#equals()', () => { it('Compares an ID with a hash, calling a callback with the result of genHash(ID) == hash.', () => { it('Hash is not equal to an empty string.', (done) => { ids[0].equals('', (err, res) => { expect(res).to.equal(false); expect(err).to.be.undefined; done(); }); }); it('Hash is equal to original ID.', (done) => { ids[0].equals(anID, (err, res) => { expect(res).to.equal(true); expect(err).to.be.undefined; done(); }); }); }); }); describe('#equalsSync()', () => { it('Compares an ID with a hash, returning the result of genHash(ID) == hash (synchronous).', () => { it('Hash is not equal to an empty string.', () => { expect(ids[0].equalsSync('')).to.equal(false); }); it('Hash is equal to original ID.', () => { expect(ids[0].equalsSync(anID)).to.equal(true); }); }); }); }); 

我的问题是,当我达到#setNewId() ,我给了以下原因testing失败: done() called multiple times 。 我明白这个错误是什么意思,但我不明白的是,当Mocha输出testing结果,当它到达#setNewId() ,它显示

 1) Create an ID ✓ Sets a new ID asynchronously. (107 ms) 

同样, #setNewIdSync()产生多个调用完成错误,但似乎是试图validation#setNewId() ; 其在摩卡的结果是

 ✓ Sets a new ID synchronously. (252 ms) 2) Sets a new ID asynchronously. 

任何帮助? 我只是在做一些愚蠢的事情?

所以,事实certificate,我正在做一些愚蠢的事情。 这只是错误地清除间隔的问题。

这个以前的代码…

 describe('#SecureID()', () => { let i = 0; let checkingFunction = (done) => { if (i == 2) { clearInterval(checkingFunction); done(); }; }; it('Create an ID', (done) => { for (let j = 0; j <= 1; j++) { ids.push(new SecureID(anID, anAmountOfRounds, (err, salt, hash) => { expect(err).to.be.undefined; expect(salt).not.to.be.undefined; expect(hash).not.to.be.undefined; i++; })); }; setInterval(checkingFunction, 100, done); }); }); 

当它不存在时尝试清除间隔checkingFunction 。 调用setInterval(checkingFunction, ...)将使用checkingFunction方法设置时间间隔,但是,所述时间间隔不存在名称checkingFunction 。 所以,修复其实很简单:

 describe('#setNewId()', () => { it('Sets a new ID asynchronously.', (done) => { let i = 0; let checkingInterval = setInterval( () => { if (i == 2) { clearInterval(checkingInterval); done(); }; }, 100); for (let j = 0; j <= 1; j++) { ids.push(new SecureID(anID, anAmountOfRounds, (err, salt, hash) => { expect(err).to.be.undefined; expect(salt).not.to.be.undefined; expect(hash).not.to.be.undefined; i++; })); }; }); }); 

let checkingInterval = setInterval( () => {let checkingInterval = setInterval( () => {创build一个新的时间间隔称为checkingInterval ,以后在asynchronoustesting完成后自行清除。