简体   繁体   中英

Jest mock async calls inside react component

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

      });
    });

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM