我正在为定制的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),它位于类组件中。组件和测试代码的代码如下所示。
使用我想要模拟的函数来简化组件的版本:
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;测试代码:
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();
  });
});发布于 2022-07-12 20:45:29
在此情况下,无需在函数loadIframe上测试逻辑。您只需查询要测试的选择器,并期望src属性应该是一个值,根据函数loadIframe的状态更改。
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')
    });
});https://stackoverflow.com/questions/72955843
复制相似问题