使用 Mocha、Chai、chaiAsPromised 和 Sinon 测试 js promises
Testing js promises with Mocha, Chai, chaiAsPromised and Sinon
我正在尝试测试读取文件的函数和 returns 对文件内容的承诺。
function fileContents(){
return new Promise(function(resolve, reject) {
fs.readFile(filename, function(err, data){
if (err) { reject(err); }
else { resolve(data); }
});
});
}
上面的单元测试
describe('Testing fileContents', function () {
afterEach(function () {
fs.readFile.restore();
});
it('should return the contents of the fallBack file', function () {
let fileContents = '<div class="some-class">some text</div>';
sinon.stub(fs, 'readFile').returns(function(path, callback) {
callback(null, fileContents);
});
let fileContentsPromise = fileContents();
return fileContentsPromise
.then(data => {
expect(data).to.eventually.equal(fileContents);
});
});
以上测试错误
Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.
我也试过了
describe('Testing fileContents', function () {
afterEach(function () {
fs.readFile.restore();
});
it('should return the contents of the fallBack file', function (done) {
let fileContents = '<div class="some-class">some text</div>';
sinon.stub(fs, 'readFile').returns(function(path, callback) {
callback(null, fileContents);
});
let fileContentsPromise = fileContents();
fileContentsPromise.then(function(data){
expect(data).to.equal(fileContents);
done();
});
});
并得到同样的错误。该功能在我的本地站点上运行,但我不知道如何为其编写测试。我是js的新手。我错过了什么?
您的代码存在多个问题。例如,您在测试中重新声明 fileContents
并为其分配一个字符串值,这当然不适用于在同一测试中执行 fileContents()
。我将专注于两个概念性问题,而不是像这个 "duh" 类型的错误。
两个概念性问题是:
要让 fs.readFile
使用假值调用您的回调,您必须使用 .yields
。使用 .returns
会更改您未使用的 return 值。所以像这样存根:
sinon.stub(fs, 'readFile').yields(null, fakeContents);
您正在 non-promise 上使用 chai-as-promised
提供的 .eventually
功能,但您必须承诺使用它才能正常工作,所以你的测试应该是:
return expect(fileContentsPromise).to.eventually.equal(fakeContents);
这是有效的代码:
const sinon = require("sinon");
const fs = require("fs");
const chai = require("chai");
const chaiAsPromised = require("chai-as-promised");
chai.use(chaiAsPromised);
const expect = chai.expect;
// We need to have filename defined somewhere...
const filename = "foo";
function fileContents(){
return new Promise(function(resolve, reject) {
fs.readFile(filename, function(err, data){
if (err) { reject(err); }
else { resolve(data); }
});
});
}
describe('Testing fileContents', function () {
afterEach(function () {
fs.readFile.restore();
});
it('should return the contents of the fallBack file', function () {
let fakeContents = '<div class="some-class">some text</div>';
sinon.stub(fs, 'readFile').yields(null, fakeContents);
let fileContentsPromise = fileContents();
return expect(fileContentsPromise).to.eventually.equal(fakeContents);
});
});
我正在尝试测试读取文件的函数和 returns 对文件内容的承诺。
function fileContents(){
return new Promise(function(resolve, reject) {
fs.readFile(filename, function(err, data){
if (err) { reject(err); }
else { resolve(data); }
});
});
}
上面的单元测试
describe('Testing fileContents', function () {
afterEach(function () {
fs.readFile.restore();
});
it('should return the contents of the fallBack file', function () {
let fileContents = '<div class="some-class">some text</div>';
sinon.stub(fs, 'readFile').returns(function(path, callback) {
callback(null, fileContents);
});
let fileContentsPromise = fileContents();
return fileContentsPromise
.then(data => {
expect(data).to.eventually.equal(fileContents);
});
});
以上测试错误
Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.
我也试过了
describe('Testing fileContents', function () {
afterEach(function () {
fs.readFile.restore();
});
it('should return the contents of the fallBack file', function (done) {
let fileContents = '<div class="some-class">some text</div>';
sinon.stub(fs, 'readFile').returns(function(path, callback) {
callback(null, fileContents);
});
let fileContentsPromise = fileContents();
fileContentsPromise.then(function(data){
expect(data).to.equal(fileContents);
done();
});
});
并得到同样的错误。该功能在我的本地站点上运行,但我不知道如何为其编写测试。我是js的新手。我错过了什么?
您的代码存在多个问题。例如,您在测试中重新声明 fileContents
并为其分配一个字符串值,这当然不适用于在同一测试中执行 fileContents()
。我将专注于两个概念性问题,而不是像这个 "duh" 类型的错误。
两个概念性问题是:
要让
fs.readFile
使用假值调用您的回调,您必须使用.yields
。使用.returns
会更改您未使用的 return 值。所以像这样存根:sinon.stub(fs, 'readFile').yields(null, fakeContents);
您正在 non-promise 上使用
chai-as-promised
提供的.eventually
功能,但您必须承诺使用它才能正常工作,所以你的测试应该是:return expect(fileContentsPromise).to.eventually.equal(fakeContents);
这是有效的代码:
const sinon = require("sinon");
const fs = require("fs");
const chai = require("chai");
const chaiAsPromised = require("chai-as-promised");
chai.use(chaiAsPromised);
const expect = chai.expect;
// We need to have filename defined somewhere...
const filename = "foo";
function fileContents(){
return new Promise(function(resolve, reject) {
fs.readFile(filename, function(err, data){
if (err) { reject(err); }
else { resolve(data); }
});
});
}
describe('Testing fileContents', function () {
afterEach(function () {
fs.readFile.restore();
});
it('should return the contents of the fallBack file', function () {
let fakeContents = '<div class="some-class">some text</div>';
sinon.stub(fs, 'readFile').yields(null, fakeContents);
let fileContentsPromise = fileContents();
return expect(fileContentsPromise).to.eventually.equal(fakeContents);
});
});