2016-11-11 27 views
0

任何人都可以幫助我在React組件中測試基於異步/ Promise的方法嗎?例如,我有以下非常簡單的陣營組成部分(這只是虛設碼)如何測試React中的異步方法?

import server from './server'; 

class Button extends Component { 
    async handleClick() { 
    if (await canDoSomething()) { 
     const result = await calculateIt(); 
     if (result) { 
     // will be mocked in my unit test 
     await server.sendResultToServer(result); 
     localStorage.setItem('sent', 'true'); 
     } 
     localStorage.setItem('sent', 'false'); 
    } 
    if (localStorage.getItem('sent') === 'true') { 
     // do something 
    } 
    } 

    render() { 
    return <button onClick={this.handleClick}>Click me</button>; 
    } 
} 

現在,在我的測試,我可以嘲笑最多的異步方法與興農像這樣:

it('should do something', async() => { 
    const promise = Promise.resolve(); 
    sinon.stub(server, 'sendResultToServer',() => promise); 
    const wrapper = shallow(<Button />); 
    wrapper.find(<button />).simulate('click'); 
    // this await will be resolved FIRST. Only then 
    // await server.sendResultToServer(result); in my code will be resolved 
    await promise; 
    expect(localStorage.getItem('sent')).to.equal('true'); 
}) 

如果你第一次看到這段代碼你應該認爲一切正常。但不幸的是,它不是。在我的測試中,我正在等待之後的承諾await promise;,這是我對我的期望。但是實現代碼也等待着這個承諾。因此,當承諾在中滿足時,都會在之前放置期望運行執行中的代碼運行。換句話說:我的測試在測試代碼之前運行(使用Mocha/Chai/Enzyme在我的機器上測試)。我需要的是顛倒的順序。

有誰知道如何解決?

+0

你永遠不呼的一下處理器在測試 –

+0

你如何測試功能handleClick()?在我的例子中,它在反應組件內。但是我可以將它寫在React組件上面,而不是導出它。所以唯一可以訪問該函數的是click處理程序。 – LongFlick

回答

0

需要觸發點擊處理:

it('should do something', async() => { 
    const promise = Promise.resolve(); 
    sinon.stub(server, 'sendResultToServer',() => promise); 
    const wrapper = shallow(<Select />); 
    wrapper.simulate('click') 
    await promise; 
    expect(localStorage.getItem('sent')).to.equal('true'); 
}) 
+0

對不起,我的不好。當我進行復制和粘貼時會發生這種情況。我已經做到了這一點,那正是我的問題:*事件發生後,承諾順序無法保證。測試中的承諾早於我的代碼中的承諾解決。我會更新/修復我的問題。 – LongFlick

+0

'canDoSomething'它來自哪裏,似乎需要嘲笑 –

+0

這是一個很好的問題。此時我的代碼中沒有「退出」。所以想象一下,我現在重定向到一條新路線。或者我在這裏什麼都不做。如果發生錯誤,我只會顯示錯誤。如果沒有發生錯誤(發送=真),我什麼都不做。 也許我在這裏有一些架構問題,我對它的看法越多。 – LongFlick