测试js承诺与Mocha,Chai,chaiAsPromised和Sinon

时间:2017-02-12 20:15:20

标签: javascript testing mocha chai

我试图测试一个读取文件的函数,并返回包含文件内容的promise。

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的新手。我错过了什么?

1 个答案:

答案 0 :(得分:1)

您的代码存在多个问题。例如,您在测试中重新声明fileContents并为其指定一个字符串值,这当然不会在同一测试中执行fileContents()。我将专注于两个概念问题,而不是像这样的&#34; duh&#34;类错误。

两个概念问题是:

  1. 要让fs.readFile使用假值调用您的回调,您必须使用.yields。使用.returns更改您不使用的返回值。所以如下:

    sinon.stub(fs, 'readFile').yields(null, fakeContents);
    
  2. 您正在使用.eventually提供的chai-as-promised功能,但您必须在承诺上使用它才能正常工作,因此您的测试应该是:< / p>

    return expect(fileContentsPromise).to.eventually.equal(fakeContents);
    
  3. 这里的代码有效:

    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);
        });
    });