2016-06-22 29 views
3

我有這樣的功能:茉莉:如何指望承諾處理程序沒有拋出異常

reload() { 
    myService.queryData() 
     .done(...) 
     .always(() => throw "fake exception"); //just to simulate the failure 
} 

我想我的測試重裝功能,並確保它不會拋出異常,也不承諾回調做。

describe("reload", function() { 
    it("does not throw exception", function (done) { 

     spyOn(myService, "queryData").and.callFake(() => { 
      let deffered = $.deffered(); 
      setTimeOut(() => deffered.reject(), 0) 
      return deffered.promise(); 
     }); 

     reload(); 
     setTimeout(() => { 
      //this is evaluated after the exception has been thrown, but 
      //how to check whether exception has been thrown 
     }, 2); 
    }); 
}); 

編輯:我可能無法在某些情況下,該函數的返回類型已經被定義返回一個承諾,如組件的生命週期事件:

MyComponent extends React.Component { 
    componentDidMount() { 
     this.load(
      galleryService.nodes().then(galleryResult => this.setState({ nodes: galleryResult.nodes })) 
     ); 
     this.load(
      galleryService.caches().then(cachesResult => this.setState({ caches: cachesResult.caches })) 
     ); 
    } 
} 

var myComponent = React.createElement(MyComponent); 
TestUtils.renderIntoDocument(myComponent); //this triggers the componentDidMount event and I need to make sure it won't throw error. 
+0

不能使用'Promise.all'或'Promise.race'協調在您的編輯片段流? – MarcoL

+0

我可以,但componentDidMount由框架(REACT)定義爲返回void的函數,我不直接調用它。當我執行'TestUtils.renderIntoDocument(...)'時,它被框架調用。我希望我可以孤立問題香草javascript,但我沒有正確闡明問題... – Liero

+0

我仍然不明白爲什麼你不能返回一個'Promise.all'包含'componentDidMount所有的承諾'或者將相關的代碼分解成一個單獨的,可測試的函數,你可以從'componentDidMount'調用。 –

回答

0

我相信,刺探window.onerror是要走的路:

describe("reload", function() { 
    it("does not throw an exception", function (done) { 

      spyOn(window, 'onerror').and.callFake((error: any, e: any) => { 
       fail(error); 
      }); 

      spyOn(myService, "queryData").and.callFake(() => { 
       let deffered = $.deffered(); 
       setTimeout(deffered.reject, 0); 
       return deffered.promise(); 
      }); 
     }); 
     setTimeout(done, 2); 
    }); 
}); 
3

reload返回的承諾它創建。在您的測試情況下,附加catch處理函數,這將觸發測試失敗:問題後

reload().catch(err => done.fail(err)); 

更新被編輯:如果你不能改變你原來的函數的返回值,那麼相關的部分分解出成單獨的功能。例如:

function reloadNodes() { 
    return somePromise(); 
} 

function reloadCaches() { 
    return anotherPromise(); 
} 

function reload() { 
    reloadNodes(); 
    reloadCaches(); 
} 

然後,您可以測試reloadNodesreloadCaches而不是reload。顯然,您不需要爲每個承諾創建一個單獨的函數,而是在適當的地方使用類似Promise.all的承諾來組合您的承諾。

+0

這是我做到的方式,但總是不可能回到承諾,看看我的編輯。 – Liero

+0

@Liero查看我的更新 –

+0

以後我會接受這個答案,因爲它回答了我的原始問題,但實際上並沒有解決我的問題。我承認我描述得很差 – Liero

相關問題