2017-02-12 5 views
0

Я пытаюсь проверить функцию, которая читается в файле, и возвращает обещание с содержимым файла.Тестирование js обещаний с Mocha, Chai, 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

С кодом возникает множество проблем. Например, вы выполните redeclare fileContents в своем тесте и назначьте ему строковое значение, которое, конечно же, не будет работать с fileContents() в том же тесте. Я собираюсь сконцентрироваться на двух концептуальных проблемах, а не на ошибках типа «duh», подобных этому.

две концептуальные проблемы:

  1. Чтобы fs.readFile вызвать ваш обратный вызов с фальшивыми ценностями вы должны использовать .yields. Использование .returns изменяет возвращаемое значение, которое вы не используете. Так незавершенная это так:

    sinon.stub(fs, 'readFile').yields(null, fakeContents); 
    
  2. Вы используете .eventually функциональные возможности, предоставляемые chai-as-promised на не-обещание, но вы должны использовать его на обещание для того, чтобы работать должным образом, ваш тест должен быть:

    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