Jest mock async calls inside react component

拈花ヽ惹草 提交于 2019-11-28 05:53:13

问题


I'm new to jest/enzyme and am trying to mock a call to an aync function that returns a Promise, the call is made inside a react component in the componentDidMount method.

The test is attempting to test that componentDidMount sets the array returned by the Promise in the state.

The issue I'm having is that the test finishes and passes before the array is added to the state. I am trying to use the 'done' callback to have the test wait until the promise resolves but this doesn't seem to work.

I have tried to move the expect calls to the line before the done() call but that doesn't seem to work either.

Can anyone tell me what I am doing wrong here?

Component being tested:

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

My test:

    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);
        });

      });
    });

回答1:


There are two problems with your test. First you cant mock AdminApiClient like this. jest.mock will replace the module with just undefined, so getItems.mockImplementation will have no effect or will throw an error. Also there is no need to use the original one. As you pass it in as an argument via props you can just create your on mock right in the test. Second, if you work with promises you either have to return the promise from your test or use async/await (docs):

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);
})


来源:https://stackoverflow.com/questions/42638889/jest-mock-async-calls-inside-react-component

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!