【问题标题】:Return different data in different mock API calls in jest开玩笑地在不同的模拟 API 调用中返回不同的数据
【发布时间】:2020-07-07 08:37:54
【问题描述】:

我开始学习更多关于使用 Jest 和 testing-library 测试 React 组件的知识。 我使用模拟 API 返回用户数据并在我的测试中呈现它,并希望在第一个 API 调用中返回 user_active = true,在第二个 API 调用中返回 user_active = false

这是我在 mocks 文件夹中用于模拟 getUsers API 的代码:

"use strict";
module.exports = {
  getUsers: () => {
    return Promise.resolve({
      data: {
        id: 27,
        full_name: "john doe",
        username: "jhon",
        is_active: true,
      },
    });
  },
}

这是我的组件,用户信息是一个包含(id、full_name、username、is_active)的对象:

  class Users extends Component {
      constructor(props) {
        super(props);
        this.state = {
          userInfo: null,
        };
      }


  getUsers = () => {
    const token = this.props.token;
    myAPI.getUsers(token)
      .then((res) => {
        this.setState({
          data: res.data,
          error: null,
        });
      })
      .catch((error) => {
        this.setState({
          error: error,
          data: [],
        });
      });
  };

  refreshList = () => {
     this.getUsers();
  };

  render() {
    return (
      <div>
       <a data-testid="refresh-button" onClick = {this.refreshList}>load user data </a>
       <span> {this.state.userInfo.username}</span>
       <span> {this.state.userInfo.is_active}</span>
      </div>
     )
    
  }


}

这是我的测试:

import React from "react";
import { render } from "@testing-library/react";
import "@testing-library/jest-dom/extend-expect";
jest.mock("../MyApi");
import Users from "./index";


  test("load users twice", async () => {
  let baseDom = render(<Users/>);//first API call  
  expect(await baseDom.findByText("true")).toBeInTheDocument();
  fireEvent.click(await baseDom.findByTestId("refresh-button")); //to second api call
  expect(await baseDom.findByText("false")).toBeInTheDocument();
});

如何在第一次/第二次 API 调用中返回不同的数据?

【问题讨论】:

  • 能否展示你的组件和组件的测试文件?
  • 是的。这是一个复杂的组件。我现在编辑了问题并添加了一些代码。

标签: reactjs api unit-testing mocking jestjs


【解决方案1】:

您可以使用jest.mockResolvedValueOnce() 方法实现此目的,查看documentation 以获取有关该方法如何工作的更多信息。

import React from "react";
import { render } from "@testing-library/react";
import "@testing-library/jest-dom/extend-expect";
import Users from "./index";
import myApi from '../MyApi'


it('should give two different results', () => {
  const firstMockReturn = {
    id: 27,
    full_name: "john doe",
    username: "john",
    is_active: true
  };
  const secondMockReturn = {
    id: 28,
    full_name: "jane doe",
    username: "jane",
    is_active: false
  };
  jest.spyOn(myApi, 'getUsers')
      .mockResolvedValueOnce(firstMockReturn) // will return to firstMockReturn object firstly
      .mockResolvedValueOnce(secondMockReturn); // will return to secondMockReturn object secondly

  let baseDom = render(<Users />)

 
  expect(await baseDom.findByText("true")).toBeInTheDocument();
  fireEvent.click(await baseDom.findByTestId("refresh-button")); //to second api call
  expect(await baseDom.findByText("false")).toBeInTheDocument();


})

【讨论】:

    【解决方案2】:

    由于这是一个模拟实现,一个简单的解决方案是记录函数 getUsers 被调用的次数,并根据该值是偶数还是奇数,将 user_active 传递为真或假。

     export default {
      _count: 0,
    
      getUsers: function() {
        this._count++;
        return Promise.resolve({
          data: {
            id: 27,
            full_name: "john doe",
            username: "jhon",
            is_active: (this._count % 2 == 0) ? true : false 
          },
        });
      },
    };
    

    【讨论】:

      【解决方案3】:

      假设我们在我们的组件中有一个自定义的 useAuth 钩子来测试,并且在我们的测试中,我们依赖于这个钩子的返回值。

      在我们的 test.js 中:

      import useAuth from "../thePath/useAuth"
      
      jest.mock('../thePath/useAuth', () => {
        return jest.fn()
      })
      

      在每个测试的每次渲染之前写下这一行之后,我们可以从我们的 useAuth 钩子中获取不同的值

      useAuth.mockImplementationOnce(() => ({user: {role: 'admin'}}))
      render(<Example />)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-09-12
        • 2019-11-08
        • 2019-05-01
        • 2022-11-12
        • 1970-01-01
        • 1970-01-01
        • 2018-05-05
        • 2019-03-28
        相关资源
        最近更新 更多