简体   繁体   English

Jest模拟异步调用内部反应组件

[英]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. 我是jest / enzyme的新手,我试图模拟对返回Promise的异步函数的调用,调用是在componentDidMount方法的react组件内部进行的。

The test is attempting to test that componentDidMount sets the array returned by the Promise in the state. 测试试图测试componentDidMount设置状态中Promise返回的数组。

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. 我正在尝试使用'done'回调让测试等待,直到promise解决但这似乎不起作用。

I have tried to move the expect calls to the line before the done() call but that doesn't seem to work either. 我试图在done()调用之前将expect调用移到该行,但这似乎也不起作用。

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. 首先你不能像这样模拟AdminApiClient jest.mock will replace the module with just undefined , so getItems.mockImplementation will have no effect or will throw an error. jest.mock将使用undefined替换模块,因此getItems.mockImplementation将不起作用或将引发错误。 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 ): 其次,如果您使用promises,则必须从测试中返回promise或使用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);
})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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