2017-02-12 138 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