首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用Jest在React类组件中模拟函数会产生“类型无效”错误

使用Jest在React类组件中模拟函数会产生“类型无效”错误
EN

Stack Overflow用户
提问于 2022-07-12 16:53:23
回答 1查看 485关注 0票数 1

我正在为定制的DataTable组件使用Jest编写测试。我还使用了React测试库。

当单击一行时,组件将加载iframe。我试图模拟加载iframe的函数,并在运行使用模拟的测试时收到一条错误消息。对于上下文,模拟此函数的目的是防止测试加载实际的iframe。

完整的错误消息是:Warning: React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object.

我的理解是,此错误消息通常发生在您错误导入模块时。但是,我不认为这是我的情况,因为组件正在导入,并在其他测试中使用,并且在这些测试中运行良好。只有具有模拟函数的组件才会产生此错误。

我该如何嘲笑这个函数呢?函数是loadIframe(id),它位于类组件中。组件和测试代码的代码如下所示。

使用我想要模拟的函数来简化组件的版本:

代码语言:javascript
运行
复制
class MyDataTable extends React.Component {
    ...
    
    // I want to mock this function
    loadIframe(id = "") {
        this.setState({iframe: `/path/to/iframe/${id}`})
    }
    
    ...
    
    render() {
        return (
            ...
            
            {this.state.iframe !== "" &&
                <iframe src={this.state.iframe}/>
            }
            
            ...
        )
    );
}
export default MyDataTable;

测试代码:

代码语言:javascript
运行
复制
import "@testing-library/jest-dom";
import { render, screen, waitFor } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import axios from "axios";
import MyDataTable from "../../components/DataTable/MyDataTable";

jest.mock("axios");

jest.mock("../../components/DataTable/MyDataTable", () => ({
  ...jest.requireActual("../../components/DataTable/MyDataTable"),
  loadIframe: jest.fn((id) => {
    // this mocked implementation will need to do something, but I've removed it from this example
  })
}));

describe("My tests", () => {
  it("should load iframe on row click", async () => {
    const data = [
        ["row 1, col 1", "row 1, col 2"],
        ["row 2, col 1", "row 2, col 2"]
    ];
    // Need to make a mock POST request to get data so a row can be clicked
    axios.post.mockResolvedValue({ data });

    // The error is thrown when render() is called here
    render(<MyDataTable id="test_id"/>);

    await waitFor(() => expect(axios.post).toHaveBeenCalled());
    
    userEvent.click(screen.getAllByRole("gridcell")[0]);
    expect(screen.getByTitle("iframe")).toBeInTheDocument();
  });
});
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-12 20:45:29

在此情况下,无需在函数loadIframe上测试逻辑。您只需查询要测试的选择器,并期望src属性应该是一个值,根据函数loadIframe的状态更改。

代码语言:javascript
运行
复制
jest.mock("axios");

describe("My tests", () => {
    it("should load iframe on row click", async () => {
        const data = [
            ["row 1, col 1", "row 1, col 2"],
            ["row 2, col 1", "row 2, col 2"]
        ];
        // Need to make a mock POST request to get data so a row can be clicked
        axios.post.mockResolvedValue({ data });

        // The error is thrown when render() is called here
        const {container} = render(<MyDataTable id="test_id"/>);

        await waitFor(() => expect(axios.post).toHaveBeenCalled());

        userEvent.click(screen.getAllByRole("gridcell")[0]);
        const iFrame = container.querySelector('iframe')

        // this step is expect `src` attribute in iFrame element should be according to state change inside function `loadiFrame`
        expect(iFrame).toHaveAttribute('src','/path/to/iframe/1')
    });
});
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72955843

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档