2017-04-02 113 views
2

我使用Jest和Enzyme來測試React組件。等待模擬呼叫中的所有承諾

我的React組件(測試中)有一個遠程選擇組件。當用戶鍵入一些文本時,將從API中提取數據並顯示選項。

test('should fetch data',() => { 
    // mock the API call 
    const store = require('../../src/store').default; 
    store.fetchData = jest.fn(() => Promise.resolve([{ 
    id: 1, 
    name: 'someText 
    }])); 

    // test 
    const wrapper = shallow(<Form />); 
    const remote = wrapper.find('RemoteSelect').first(); 
    remote.simulate('fetch', 'someText'); 
    expect(store.fetchData).toBeCalled(); 

    // more test 
    remote.simulate('change', 1); 
    const remoteRequeried = wrapper.find('RemoteSelect').first(); 
    expect(remoteRequeried.prop('label')).toBe('someText'); 
}); 

當用戶鍵入一些文本時,第一個測試會從存儲中提取數據。第二個測試選擇一個選項。第二次測試失敗。

這是一個很難解釋這是一個SO問題。這些選項設置在Promise的「then」部分。在第二次模擬之前,「然後」函數沒有得到執行。所以,當第二次模擬被觸發時,這些選項不會被設置。

如果我在setTimeout()中移動第二個測試,則第二個測試通過。

無論如何Jest確保承諾的「時間」在執行更多測試之前得到執行嗎?

回答

1

你可以做這樣的事情:

test('should fetch data',() => { 
    // mock the API call 
    const store = require('../../src/store').default; 
    let promise; 
    store.fetchData = jest.fn(() => { 
    promise = Promise.resolve([{ 
     id: 1, 
     name: 'someText', 
    }]); 
    return promise; 
); 

    // test 
    const wrapper = shallow(<Form />); 
    const remote = wrapper.find('RemoteSelect').first(); 
    remote.simulate('fetch', 'someText'); 
    expect(store.fetchData).toBeCalled(); 

    return promise.then((result) => { 
    // more test 
    remote.simulate('change', 1); 
    const remoteRequeried = wrapper.find('RemoteSelect').first(); 
    expect(remoteRequeried.prop('label')).toBe('someText'); 
    }); 
}); 
+0

感謝。工作得很好。 – vijayst