NodeJStesting承诺

我正在尝试学习NodeJS中的testing承诺,而且我在其他语言中使用的testing方法在这里还是让我失望了。 基本的问题是“如何有效地testing一个或多个链接的(完成或捕获的)承诺块的间接input和输出?

这里是lib/test.js的源代码:

 var Bluebird = require("bluebird"), fs = Bluebird.promisifyAll(require("fs")); function read(file) { return fs.readFileAsync(file) .then(JSON.parse) .done(function () { console.log("Read " + file); }); } function main() { read("test.json"); } if (require.main === module) { main(); } module.exports = read; 

这里是tests/test.js的来源

 var Bluebird = require("bluebird"), chai = require("chai"), expect = chai.expect, sinon = require("sinon"), sandbox = sinon.sandbox.create(), proxyquire = require("proxyquire"); chai.use(require("chai-as-promised")); chai.use(require("sinon-chai")); describe("test", function () { var stub, test; beforeEach(function () { stub = { fs: { readFile: sandbox.stub() } } test = proxyquire("../lib/test", stub); }); afterEach(function () { sandbox.verifyAndRestore(); }); it("reads the file", function () { test("test.json"); expect(stub.fs.readFile).to.have.been.calledWith("test.json"); }); it("parses the file as JSON", function () { stub.fs.readFileAsync = sandbox.stub().returns(Bluebird.resolve("foo")); sandbox.stub(JSON, "parse"); test("test.json"); expect(JSON.parse).to.have.been.calledWith("foo"); }); it("logs which file was read", function () { stub.fs.readFileAsync = sandbox.stub(); sandbox.stub(JSON, "parse"); test("bar"); expect(console.log).to.have.been.calledWith("Read bar") }); }); 

我意识到这些例子是微不足道的,但是我正在试图理解如何testing承诺链,而不是如何读取文件并将其parsing为JSON。 🙂

另外,我没有绑定任何框架或类似的东西,所以如果我在抓取任何包含的NodeJS库的时候无意中select了糟糕的function,那么也可以使用call-out。

谢谢!

假设语法是摩卡,你需要返回承诺。 所有的承诺都是按照返回值的方式工作的,所以如果你不从testing中返回它们,testing库就不能挂钩它们。

 describe("testing promises with mocha", () => { it("works by returning promises", () => { return Promise.resolve("This test passes"); }); it("fails by returning promises", () => { return Promise.reject(Error("This test fails")); }); it("Lets you chain promises", () => { return fs.readFileAsync("test.json").then(JSON.parse); }); }); 

(新的function箭头语法在NodeJS中工作,如果您需要支持旧节点 – 将其转换为function(){调用)

@Benjamin Gruenbaum

我结束了以下在lib/test.js

 var Bluebird = require("bluebird"), fs = Bluebird.promisifyAll(require("fs")); function read(files) { return Bluebird.map(files, function (file) { return fs.readFileAsync(file) .then(JSON.parse) .then(function (data) { console.log("Read " + file); }); }); } function main() { read(["test.json", "test2.json"]); } if (require.main === module) { main(); } module.exports = read; 

这是tests/test.js

 var Bluebird = require("bluebird"), chai = require("chai"), chaiAsPromised = require("chai-as-promised"), expect = chai.expect, sinon = require("sinon"), sandbox = sinon.sandbox.create(), proxyquire = require("proxyquire"); chai.use(chaiAsPromised); chai.use(require("sinon-chai")); describe("test", function () { var stub, test; beforeEach(function () { stub = { fs: { readFile: sandbox.stub() } }; sandbox.stub(JSON, "parse"); test = proxyquire("../lib/test", stub); stub.fs.readFileAsync = sandbox.stub().returns(Bluebird.resolve()); }); afterEach(function () { sandbox.verifyAndRestore(); }); it("reads the files", function () { var files = ["test.json", "test2.json"]; return test(files).then(function () { var expects = files.map(function (file) { return expect(stub.fs.readFileAsync).to.have.been.calledWith(file); }); // expects.push(expect(Bluebird.resolve(1)).to.eventually.equal(2)); return Bluebird.all(expects); }); }); it("parses the files as JSON", function () { var returns = ["foo", "bar"]; returns.forEach(function (value, index) { stub.fs.readFileAsync.onCall(index).returns(Bluebird.resolve(value)); }); return test(["baz", "buz"]).then(function () { var expects = returns.map(function (value) { return expect(JSON.parse).to.have.been.calledWith(value); }) // expects.push(expect(Bluebird.resolve(1)).to.eventually.equal(2)); return Bluebird.all(expects); }); }); it("logs which files were read", function () { var files = ["bleep", "blorp"]; sandbox.spy(console, "log"); return test(files).then(function () { var expects = files.map(function (file) { return expect(console.log).to.have.been.calledWith("Read " + file); }); // expects.push(expect(Bluebird.resolve(1)).to.eventually.equal(2)); return Bluebird.all(expects); }); }); }); 

我在那里留下了1 === 2的断言,以确保我没有得到误报(比如当一个.then不会被调用,因为我做错了)。