我正在尝试学习在NodeJS中测试承诺,而我在其他语言中使用的测试方法在这里让我失望了。基本问题是"如何在一个或多个链接然后(和完成或捕获)承诺块中有效地测试间接输入和输出?"
这里是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")
});
});
我意识到这些例子是微不足道的,但是我希望尝试理解如何测试承诺链,而不是如何读取文件并将其解析为JSON。 :)
此外,我并没有依赖于任何框架或类似的东西,所以如果我在抓取任何包含的NodeJS库时无意中选择了不好的话,那么也会感激呼出。
谢谢!
答案 0 :(得分:2)
假设语法是Mocha,您需要返回承诺。当你从方法中返回它们之后,所有的promises都按返回值工作,所以如果你不从测试中返回它们,那么测试库就无法挂钩它们。
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);
});
});
(新功能箭头语法适用于NodeJS,如果您需要支持旧节点 - 将其转换为function(){
个调用)
答案 1 :(得分:1)
@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
因为我做错了而无法调用Employee.objects.all().prefetch_related('group_set')