如何在JavaScript中testing基于生成器的stream量控制(ES6)?

如何让Mocha等到asynchronousfunction完成?

var fs = require('mz/fs'); var co = require('co'); module.exports = new filecache(); function filecache () { var self = this; var storage = storage || {}; self.cache = co(function* (filePath, fileName) { if (yield fs.exists(filePath)) { storage[fileName] = yield fs.readFile(filePath); } }); self.has = function has (fileName) { return storage.hasOwnProperty(fileName); }; } 

testing(摩卡)

 var expect = require('chai').expect; describe('phialcash', function () { var filecache; var filePath; var fileName; beforeEach(function () { filecache = require('..'); filePath = './tests/file.fixture.txt'; fileName = filePath.split("/").pop(); }); describe('#exists', function () { it('returns true if a file exists in the cache', function () { filecache.cache(filePath, fileName); expect(filecache.has(fileName)).to.equal(true); }); }); }); 

testing失败,因为filecache.cache(filePath, fileName); 执行asynchronous,所以filecache.has(fileName)在运行期望时仍然是错误的。

您应该在方法调用的站点使用co ,而不是在定义中使用。

 self.cache = function* (filePath, fileName) { if (yield fs.exists(filePath)) { storage[fileName] = yield fs.readFile(filePath); } }; 

testing时,将该函数标记为asynchronous并传递给协程。 co将调用已done参数donecallbackdone(err, response) 。 asynchronous调用中抛出的任何exception或失败的expect都会导致testing用例失败。

 describe('#exists', function () { it('returns true if a file exists in the cache', function (done) { co(function * () { yield *filecache.cache(filePath, fileName); //generator delegation. expect(filecache.has(fileName)).to.equal(true); })(done); }); }); 

这是一个使用koa的应用程序摘录,它在内部使用co来处理控制stream。 所有产生的语句都是返回thunksasynchronous调用。

 group.remove = function * (ids) { var c3Domain = this.c3Domain; let deletedCount = yield this.baseRemove(ids); if(deletedCount > 0) { let deletedGroupMappings = yield [this.connection.query(UNMAP_GROUPS, [this.c3Id, ids]), this.tag.unmapGroupTags(ids)]; let deletedQueueCount = yield this.removeQueuesFromXml(ids); if(deletedQueueCount > 0) { let eslCommands = ['reloadxml'].concat(ids.map(function (id) { return ['callcenter_config queue unload', id + '@' + c3Domain]; })); yield this.esl.multiApi(eslCommands); } } return deletedCount; }; 

testing用例:

 it('should delete group', function (done) { co(function *() { let count = yield group.remove(['2000']) assert(count === 1) })(done) })