【问题标题】:Jest Asynchronous API MockingJest 异步 API 模拟
【发布时间】:2019-01-23 08:34:32
【问题描述】:

我在 stack-overflow 上搜索过这个问题,但找不到与我类似的用例。

我有这样的容器组件。

import React, { Component } from 'react';
import PropTypes from 'prop-types';

// API
import BookingAPI from '../../../../api/BookingAPI';

class CustomerProfilePage extends Component {
  state = {
    list: [],
    totalRecords: 0,
    pageNo: 1,
  };

  componentDidMount() {
    const { pageNo } = this.state;
    this.onGetBookingList({ pageNo });
  }

  onGetBookingList = async ({ pageNo = 0 }) => {
    const { match } = this.props;
    try {
      const result = await BookingAPI.onGetBookingList({
        passengerId: match.params.customerId,
        sortProperties: ['id'],
        limitCount: 10,
        pageNo,
      });
      this.setState({
        list: result.items,
        totalRecords: result.totalRecords,
     });
    } catch (error) {
      // console.log('error is', error);
    }
  };

  render() {
    return <div></div>;
  }
}

export default CustomerProfilePage;

我想在我的this.onGetBookingList 方法中测试BookingAPI.onGetBookingList

到目前为止,这是我尝试过的,我在这里遗漏了什么..

这是我下面的CustomerProfilePage.test.js 文件

import React from 'react';
import { shallow } from 'enzyme';

// Components
import CustomerProfilePage from './CustomerProfilePage';

function setup() {
  const props = {
     match: {
       params: {
         customerId: 1,
       },
     },
  };
  return shallow(<CustomerProfilePage {...props} />);
}

describe('CustomerProfilePage', () => {
  it('Should update state on onGetBookingList call', async () => {
    jest.mock('../../../../api/BookingAPI', () => ({
      onGetBookingList: () => {
        const data = { items: [{ value: 1 }, { value: 2 }], totalRecords: 1 };
        return jest.fn().mockReturnValue(data);
      },
    }));
    const wrapper = setup();
    await wrapper.instance().onGetBookingList({ pageNo: 1 });
    wrapper.update();
    expect(wrapper.state().totalRecords).toBe(1); // should be 1, but is 0
 });
});

为了简单起见,我没有在render 中编写代码,因为我想专注于我正在模拟 API 调用的代码部分。

【问题讨论】:

    标签: reactjs mocking jestjs enzyme


    【解决方案1】:

    因为onGetBookingList 必须是异步函数

    你可以像这样定义异步方法:

    jest.mock('../../../../api/BookingAPI', () => ({
        async onGetBookingList() {
            return data;
        }
    }));
    

    或者你可以使用 jest.fn() 来返回一个 Promise

    jest.mock('../../../../api/BookingAPI', () => ({
        onGetBookingList: jest.fn(() => Promise.resolve(data))
    }));
    

    或使用 jest.fn().mockResolvedValue()

    jest.mock('../../../../api/BookingAPI', () => ({
        onGetBookingList: jest.fn().mockResolvedValue(data)
    }));
    

    然后

    import { onGetBookingList } from '../../../../api/BookingAPI';
    
    it('should be working with all of the above mocks', async () => {
        const { totalRecords } = await onGetBookingList();
        expect(totalRecords).toBe(1);
    }
    

    working exmaple

    【讨论】:

    • 谢谢,有没有办法可以在我的测试中调用this.onGetBookingList 并从该函数测试BookingAPI.onGetBookingList 方法,而不是直接测试它。另外,如果我直接测试它,我的代码覆盖率会像这样覆盖吗?
    • 上面的测试证明了 mock 可以正常工作。你不需要直接测试它。它应该由您正在测试的实现调用,因为它依赖于 BookingAPI
    • 我知道,这就是困扰我的问题。你的测试有效,但我的覆盖率仍然不是 100%,因为 jest 没有覆盖 this.onGetBookingList 内的行我可以像这样测试每个 API,但我的代码仍然没有覆盖这些方法。
    • Jest 的报道报告工作得很好,也许你应该问一个新问题,这里是题外话
    • 感谢您的支持。
    猜你喜欢
    • 2021-08-11
    • 2021-01-10
    • 1970-01-01
    • 2023-03-11
    • 2019-03-13
    • 1970-01-01
    • 2021-07-03
    • 2019-02-25
    • 1970-01-01
    相关资源
    最近更新 更多