2017-02-12 135 views
0

我试图测试一个函数,读取文件并返回一个承诺与文件的内容。测试js承诺与摩卡,柴,chaiAsPromised和Sinon

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

您的代码有多个问题。例如,您在您的测试中重新声明fileContents并为其分配一个字符串值,在同一测试中这当然不适用于fileContents()。我将专注于两个概念性问题,而不是像这样的“呃”类型的错误。

这两个概念上的问题是:

  1. 要让fs.readFile调用你的回调与您必须使用.yields假值。使用.returns更改您不使用的返回值。所以存根这样的:

    sinon.stub(fs, 'readFile').yields(null, fakeContents); 
    
  2. 您使用的是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); 
    }); 
}); 
+0

产量正是我正在寻找,非常感谢你。对于有变数名称的红鲱鱼,我的原始代码中没有;我已经将代码更改为更通用的代码,并没有注意到我已经为'假内容'和函数名称使用了相同的名称。无论如何,再次感谢! – margo