2015-09-30 50 views
1

我一直在努力,現在直接運行該測試2天,我想不出有什麼不對的地方:摩卡測試超時使用承諾和跳過代碼,爲什麼?

/*eslint-env mocha */ 
// var expect = require('chai').expect; 
var chai = require('chai'); 
var chaiAsPromised = require("chai-as-promised"); 
var expect = chai.expect; 
var Promise = require('bluebird'); 
var Archive = require('../lib/archive'); 
var path = require('path'); 
var fs = Promise.promisifyAll(require('fs-extra')); 
var globAsync = Promise.promisify(require('glob')); 
var tar = require('tar-fs'); 
var zlib = Promise.promisifyAll(require('zlib')); 

chai.use(chaiAsPromised); 

describe('Archive', function() { 
    var pkg; 
    var archive_location; 
    var subject; 

    beforeEach(function() { 
    pkg = { 
     name: 'test_0790feebb1', 
     recipient_name: 'Test', 
     files: { 
     letter: '../documents/letters/test/letter.tex', 
     resume: '../documents/cover/cover.tex' 
     }, 
     compiled_files: { 
     package: '../documents/letters/test/test.pdf' 
     } 
    }; 
    archive_location = path.resolve('archives/test_0790feebb1.tar.gz'); 

    subject = new Archive(pkg); 
    }); 

    after(function() { 
    return globAsync('archives/test*') 
     .each(function(filename) { 
     return fs.removeAsync(filename); 
     }); 
    }); 

    describe('#make', function() { 
    it('has the correct directory structure', function() { 
     // debugger; 
     var tmp_extract_path = path.resolve('test/.tmp'); 
     var tarPromise = function(data) { 
     console.log('tarP'); // never run 
     return new Promise(function(reject, resolve) { 
      data 
      .pipe(zlib.Unzip()) 
      .pipe(tar.extract(tmp_extract_path)) 
      .on('error', reject) 
      .on('end', resolve); 
     }); 
     }; 

     var verifyDir = function() { 
     console.log('verD'); // never run 
     return Promise.all([ 
      'code', 
      'pdf', 
      'code/repo', 
      'code/documents', 
      'code/documents/letters', 
      'code/documents/letters/test', 
      'code/documents/letters/shared', 
      'code/documents/cover', 
      'code/documents/letters' 
     ].map(function(subpath) { 
      return fs.statAsync(path.resolve(tmp_extract_path, subpath)); 
     })); 
     }; 

     return fs.createReadStreamAsync(archive_location) 
     .then(function(data) { return tarPromise(data); }) 
     .then(function() { return verifyDir(); }) 
     .then(function(files) { 
      console.log(files); // never run 
      return expect(true).to.be.true; 
     }) 
     .catch(function(e) { console.log(e); }); 
    }); 
    }); 
}); 

各種的console.log從來沒有得到執行,並最終測試超時無任何錯誤或堆棧跟蹤。

我不知道我做錯了什麼,承諾傷害了我的大腦。當我用節點檢查器運行代碼並取消註釋斷點時,我可以看到他的值爲this._runnable._trace"done() called multiple times"。我不知道這是否是一個實際的錯誤,也不知道如果這是一個錯誤,它不會拋出異常。因爲我沒有使用任何done()回調再和承諾,而我的測試與function()而不是function(done)開始像一個異步測試將

任何想法,我無法解釋或者這是爲什麼即使發生?

+0

我看到的兩個問題是:函數'tarPromise'返回undefined,不是promise,並且'verifyDir'不在鏈中調用,只是傳遞。此外,在承諾鏈中添加catch塊可能有助於確定問題...... – mido

+0

我的糟糕之處在於,我在爲SO格式化代碼時犯了拼寫錯誤。我編輯了這個問題來糾正錯誤。我還添加了一個catch塊,但是在運行代碼時它從不打印任何東西。 – springloaded

+1

proabably [this issue](https://github.com/petkaantonov/bluebird/issues/225)? – mido

回答

2

你的問題是fs.createReadStream是同步的,並返回一個ReadableStream,它以塊的形式將數據讀入內存。 PromisifyAll將回調函數轉換爲承諾的異步函數,而不是將同步函數轉換爲異步函數。

也許你想要的是使用fs.readFileAsync

var Promise = require('bluebird'); 
var fs = Promise.promisifyAll(require('fs')); 
var path = require('path') 
var archive_location = path.resolve('example.zip'); 
var assert = require('assert'); 

describe('This', function(){ 
    it('should work', function(){ 
     return fs.readFileAsync(archive_location). 
      then(function(data) { 
       assert.notEqual(data.length, data.length); 
       return data; 
      }). 
      catch(console.log); 
    }); 
}); 

我斷言設置爲一個失敗的斷言來證明,這實際上打的承諾鏈。

+0

謝謝你,根據你的回答,我結束了在tarPromise中移動fs.createReadStream並解決了問題。 我希望createReadStreamAsync將流傳遞到next(),但事實並非如此。 如果你的解決方案使用緩衝區,你的解決方案可以工作,我想堅持使用流,因爲我的tar.extract與流協同工作。 – springloaded

+0

如果您再次遇到該問題,則可以使用流封裝緩衝區。請參閱http://stackoverflow.com/a/16044400/151445這並不能避免將整個文件讀入內存緩衝區的問題,但它確實修飾了要由tar.extract使用的緩衝區。如果你的圖書館是公開的,它甚至可以很好地向用戶公開。 –