2017-03-07 124 views
0

我是新來的jest /酶,我試圖模擬對返回Promise的異步函數的調用,調用是在componentDidMount方法中的反應組件內進行的。Jest模擬異步調用內部反應組件

測試正在嘗試測試componentDidMount設置狀態中Promise返回的數組。

我遇到的問題是測試在數組添加到狀態之前完成並通過。我正在嘗試使用'done'回調讓測試等待,直到承諾解決,但這似乎不起作用。

我已經嘗試在done()調用之前將預期調用移動到該行,但似乎也不起作用。

任何人都可以告訴我我在做什麼錯嗎?

組件進行測試:

componentDidMount() { 
    this.props.adminApi.getItems().then((items) => { 
    this.setState({ items}); 
    }).catch((error) => { 
    this.handleError(error); 
    }); 
} 

我的測試:

import React from 'react'; 
    import { mount } from 'enzyme'; 
    import Create from '../../../src/views/Promotion/Create'; 

    import AdminApiClient from '../../../src/api/'; 
    jest.mock('../../../src/api/AdminApiClient'); 

    describe('view',() => { 

     describe('componentDidMount',() => { 

     test('should load items into state', (done) => { 
      const expectedItems = [{ id: 1 }, { id: 2 }]; 

      AdminApiClient.getItems.mockImplementation(() => { 
      return new Promise((resolve) => { 
       resolve(expectedItems); 
       done(); 
      }); 
      }); 

      const wrapper = mount(
      <Create adminApi={AdminApiClient} /> 
     ); 

      expect(wrapper.state().items).toBe(expectedItems); 
     }); 

     }); 
    }); 

回答

5

有兩個問題與您的測試。首先你不能模擬AdminApiClient這樣。 jest.mock將用undefined替換模塊,因此getItems.mockImplementation將不起作用或將引發錯誤。也沒有必要使用原來的。當你通過道具傳遞它作爲參數時,你可以在測試中直接創建你的模型。第二,如果你與承諾工作,你要麼必須從測試返回的承諾或使用async/awaitdocs):

it('', async() = > { 
    const expectedItems = [{ id: 1 }, { id: 2 }]; 
    const p = Promise.resolve(expectedItems) 
    AdminApiClient = { 
    getItems:() = > p 
    } 
    const wrapper = mount(
    <Create adminApi={AdminApiClient} /> 
); 
    await p 
    expect(wrapper.state().items).toBe(expectedItems); 
}) 
+0

感謝您的解釋,這種方法很好地工作!也可以通過使用Promise.reject()和try/catch塊並在p.catch()上等待來測試錯誤情況。 – lachy