2

我正在尝试使用@testing-library/react 测试使用useAsync挂钩的组件。

如果我在 TestAPI 模块上使用 jest.mock,然后是 getTest.mockResolvedValueOnce(testArray); 在 getTest 函数上,我希望模拟能够正确返回测试值。

测试 :

import React from "react";
import { render, screen, waitFor } from "@testing-library/react";
import TestPanel from "./TestPanel";
import { getTest } from "./TestAPI";

jest.mock("./TestAPI");

it("renders cards correctly", async () => {
  const testArray = ["hi there"];
  getTest.mockResolvedValueOnce(testArray);

  render(<TestPanel />);

  expect(getTest).toHaveBeenCalledTimes(1);
  expect(getTest).toHaveBeenCalledWith();

  await waitFor(() => expect(screen.getByText("hi there")).toBeInTheDocument());
});

要测试的组件:

import React from "react";
import { useAsync } from "react-async-hook";
import { getTest } from "./TestAPI";

export default function TestPanel() {
  const { result: elems } = useAsync(getTest, []);

  return (
    <div>
      {elems &&
        elems.map((elem) => {
          return <div>{elem}</div>;
        })}
    </div>
  );
}

API调用:

import React from "react";
import axios from "axios";

export async function getTest(): Promise {
  const response = await axios.get("/someservice");

  return response.data || [];
}

但是,如果我运行测试,则会引发异常,说明“elems.map”未定义。

仔细观察,elems 似乎是一个承诺。

在此处输入图像描述

有什么我做错了吗?

4

2 回答 2

1

这些是你的问题:react-async-hook & jest

这里 react-async-hook使用instanceof PromiseJest.mockResolvedValueOnce返回的不是真正的 JS Promise,而是类似 Promise 的对象。因此,useAsync()将模拟视为 sycn 函数。

解决方案是使用mockImplementationOnce而不是mockResolvedValueOnce

getTest.mockImplementation(async () => testArray)

文档

mockFn.mockResolvedValueOnce(值)

语法糖功能:

jest.fn().mockImplementationOnce(() => Promise.resolve(value));

但是,可悲的是,它不仅仅是一种语法糖。

于 2021-09-10T17:34:41.630 回答
0

我认为你应该嘲笑你从 useAsync 钩子本身返回。

jest.mock("path/to/useAsync", () => ({
  result: ["test"]
}));`
于 2021-09-06T12:25:47.637 回答