2015-10-09 35 views
3

我正在測試一些使用承諾chai-as-promisedMocha的代碼。我的測試套件也利用fetch-mock來模擬通常使用Fetch API發送的AJAX請求。爲什麼這個chai-as-promised AssertionError打印到控制檯而不是我的摩卡測試運行器?

這裏有我想要的測試代碼:

/** 
* Sends a POST request to save (either insert or update) the record 
* @param {object} record simple object of column name to column value mappings 
* @return {Promise}  Resolves when the POST request full response has arrived. 
* Rejects if the POST request's response contains an Authorization error. 
*/ 
save(record) { 
    var _this = this; 
    return this._auth(record) 
    .then(function() { 
     return window.fetch(_this._getPostUrl(), { 
     method: 'post', 
     headers: { 
      'Content-type': 'application/x-www-form-urlencoded; charset=UTF-8' 
     }, 
     body: _this._objToPostStr(record), 
     credentials: 'include' 
     }); 
    }) 
    .then(function(saveResp) { 
     return saveResp.text(); 
    }) 
    .then(function(saveResp) { 
     return new Promise(function(resolve, reject) { 
     if (saveResp.indexOf('Authorization') !== -1) { 
      reject('Request failed'); 
     } else { 
      resolve(saveResp); 
     } 
     }); 
    }); 
} 

在我最上層describe,我有這個功能最初設置了我fetchMock對象。

before(() => { 
    fetchMock = new FetchMock({ 
    theGlobal: window, 
    Response: window.Response, 
    Headers: window.Headers, 
    Blob: window.Blob, 
    debug: console.log 
    }); 
    fetchMock.registerRoute({ 
    name: 'auth', 
    matcher: /tlist_child_auth.html/, 
    response: { 
     body: 'authResp', 
     opts: { 
     status: 200 
     } 
    } 
    }); 
}); 

和這裏的相關測試代碼:

describe('save',() => { 
    it('save promise should reject if response contains the string Authorization',() => { 

    fetchMock.mock({ 
     routes: ['auth', { 
     name: 'save', 
     matcher: /changesrecorded.white.html/, 
     response: { 
      body: 'Authorization', 
      opts: { 
      status: 200 
      } 
     } 
     }] 
    }); 

    let _getLocationStub = sinon.stub(client, '_getLocation'); 
    _getLocationStub.returns('/admin/home.html'); 

    client.foreignKey = 12345; 
    let promise = client.save({ 
     foo: 'bar' 
    }); 
    promise.should.eventually.be.fulfilled; 
    fetchMock.unregisterRoute('save'); 
    }); 
}); 

我定義的fetchMock.mock()呼叫save路線是我需要的save路線另一個測試,以重新定義返回的東西的原因其他。

爲了確保chai-as-promise實際工作正常,並會通知我失敗的測試,我寫了一個失敗的測試promise.should.eventually.be.fulfilled;。這將失敗,因爲save返回的承諾將拒絕如果響應包含Authorization,它會這樣做。 Chrome控制檯顯示message: expected promise to be fulfilled but it was rejected with 'Request failed AssertionError,但我的摩卡test-runner.html頁面顯示此測試通過。出於某種原因,chai-as-promise沒有與Mocha正確溝通。

如果您希望看到我的整個項目,請參閱Github上的this repo

任何想法爲什麼?

編輯:

這裏是我的測試設置代碼:

let expect = chai.expect; 
mocha.setup('bdd'); 
chai.should(); 
chai.use(chaiAsPromised); 

回答

4

promise.should.eventually.be.fulfilled是一個承諾,你應該返回,這樣可以摩卡知道什麼時候你的測試已經結束。我已經創建了一個小型測試文件來模擬你所看到的,如果你像我一樣,我只是不能返回promise.should.eventually.be.fulfilled;,我可以完全複製行爲。這裏是工作的例子:

import chai from "chai"; 
import chaiAsPromised from "chai-as-promised"; 

chai.use(chaiAsPromised); 
chai.should(); 

describe("foo",() => { 
    it("bar",() => { 
     let promise = Promise.reject(new Error()); 
     return promise.should.eventually.be.fulfilled; 
    }); 
}); 

在你的代碼在測試的最後有一些清理代碼:fetchMock.unregisterRoute('save');。根據你展示的內容,我會將其移至after掛鉤,以便它反映你的before掛鉤。一般而言,after應該執行與beforeafterEach中的內容相對應的清理,以對應於beforeEach中的內容。但是,如果您需要有某種原因,在測試裏面清理代碼,你可以這樣做:

 function cleanup() { 
      console.log("cleanup"); 
     } 

     return promise.should.eventually.be.fulfilled.then(
      // Called if there is no error, ie. if the promise was 
      // fullfilled. 
      cleanup, 
      // Called if there is an error, ie. if the promise was 
      // rejected. 
      (err) => { cleanup(); if (err) throw err; }); 

不幸的是,柴似乎返回一些東西,看起來像一個ES6 Promise但只有部分。最終,它可能會返回一個實際的ES6承諾,然後您可以撥打.finally來運行清理代碼,無論發生什麼情況,並將錯誤自動傳播。

+0

似乎很明顯,文檔在閱讀本文後一直這樣說。謝謝你的回答! –

相關問題