gpt4 book ai didi

reactjs - 如何在我的 react 测试中模拟状态和数据的值

转载 作者:行者123 更新时间:2023-12-03 23:41:49 25 4
gpt4 key购买 nike

我正在为我的 react 页面编写测试,但我的页面在其状态下使用 isLoading,加载页面时呈现“正在加载”,加载时但没有数据(来自获取请求)呈现“未找到数据”和加载时数据(来自获取请求)加载欢迎页面。
我想编写一个测试来检查在以下情况下显示的预期文本:

  • 页面已加载但未找到数据
  • 页面已加载并有数据

  • 我想我已经设法让数据测试无法正常工作,但是当我尝试模拟它返回的数据时出现错误消息。错误信息是
    TypeError: Cannot read property 'map' of undefined

    但我不确定为什么我的模拟数据是 data: orders > 里面有数据所以不应该是未定义的。
    有人可以告诉我如何更正测试吗?
    欢迎页面.js
    import React from "react";
    import { Link } from "react-router-dom";

    class WelcomePage extends React.Component {
    constructor(props) {
    super(props);
    this.state = {
    data: [],
    isLoading: false,
    };
    }

    componentDidMount() {
    this.setState({ isLoading: true });
    const proxyurl = "https://cors-anywhere.herokuapp.com/";
    const url =
    "mu url"
    fetch(proxyurl + url)
    .then((res) => res.json())
    .then((data) => this.setState({ data: data, isLoading: false }));
    }

    render() {
    const { data, isLoading } = this.state;
    if (isLoading) {
    return (
    <div className="pageLoading">
    <p>Loading...</p>
    </div>
    );
    }
    if (data.length === 0) {
    return <p> no data found</p>;
    }
    return (
    <div className="Welcome">
    <div className="Details">
    <p className="userID">
    <strong>
    Welcome {data.userForename} {data.userSurname}
    </strong>
    </p>
    <button className="SignOut">
    <Link to={{ pathname: "/LogIn" }}>Sign Out</Link>
    </button>
    </div>
    <div className="InfoBox">
    <p>
    <strong>Orders</strong>{" "}
    </p>
    </div>
    <div className="orderss">
    {data.orders.map((order, index) => (
    <ul className="orderBox" key={order.toString()+index}>
    <li className="orderLink">
    <Link
    to={{
    pathname: "/OrderDetails",
    state: {
    orderNumber: order.rollNumber,
    userID: this.state.userID,
    },
    }}
    >
    Order number: {order.rollNumber}
    </Link>
    </li>
    <li> Customer name: {order.customerFullName}</li>
    </ul>
    ))}
    </div>
    </div>
    );
    }
    }

    export default WelcomePage;
    欢迎.page.test.js
    import React, { useState } from 'react';
    import renderer from 'react-test-renderer';
    import {render, unmountComponentAtNode } from 'react-dom';
    import WelcomePage from './WelcomePage';

    let container = null;

    beforeEach(() => {
    container = document.createElement('div');
    document.body.appendChild(container);
    })

    afterEach(() => {
    unmountComponentAtNode(container);
    container.remove();
    container = null;
    })

    test("test page renders as epxected when loading", () => {
    const userId= "123456";
    render(<WelcomePage location={userId}></UserWelcome>, container);
    expect(container.innerHTML).toContain("Loading...");
    });

    test("mock fetch call, empty responce from db should return no data",
    async () => {
    const fakeResponse = [];
    const userId = "1234567";

    jest.spyOn(window, "fetch").mockImplementation(() => {
    const fetchResponse = {
    json: () => Promise.resolve(fakeResponse),
    };
    return Promise.resolve(fetchResponse);
    });

    await act(async () => {
    render(<WelcomePage location={userId} />, container);
    });

    expect(container.innerHTML).toContain("no data");

    window.fetch.mockRestore();
    }
    );

    test("mock fetch call, valid responce from db should return applications", async () => {
    //{ rates: { CAD: 1.42 } }
    const fakeResponse = [
    {
    data: {
    userId: 1234567,
    userForename: "Joe",
    userSurname: "Bloggs",
    orders: [
    {
    orderNumber: 10000000001,
    customerFullName: "Mrs Joes Bloggs",
    userId: 1234567
    },
    ]
    }
    }
    ];
    const userId = "1234567";

    jest.spyOn(window, "fetch").mockImplementation(() => {
    const fetchResponse = {
    json: () => Promise.resolve(fakeResponse)
    };
    return Promise.resolve(fetchResponse);
    });

    await act(async () => {
    render(<WelcomePage location={userId} />, container);
    });

    expect(container.textContent).toContain("Order number: 10000000001");

    window.fetch.mockRestore();
    });

    编辑 - 添加 package.json
    {
    "name": "sm-app",
    "version": "0.1.0",
    "private": false,
    "dependencies": {
    "@testing-library/jest-dom": "^4.2.4",
    "@testing-library/react": "^9.5.0",
    "@testing-library/user-event": "^7.2.1",
    "bootstrap": "^4.5.3",
    "moment": "^2.29.1",
    "prop-types": "^15.7.2",
    "react": "^17.0.1",
    "react-app-polyfill": "^2.0.0",
    "react-bootstrap": "^1.4.0",
    "react-dom": "^17.0.1",
    "react-router-dom": "^5.2.0",
    "react-scripts": "3.4.4",
    "react-spinners": "^0.9.0",
    "reactstrap": "^8.6.0"
    },
    "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
    },
    "eslintConfig": {
    "extends": "react-app"
    },
    "browserslist": {
    "production": [
    ">0.2%",
    "not dead",
    "not op_mini all",
    "ie >= 9"
    ],
    "development": [
    "last 1 chrome version",
    "last 1 firefox version",
    "last 1 safari version",
    "ie 11"
    ]
    },
    "devDependencies": {
    "prettier": "2.1.2",
    "react-test-renderer": "^17.0.1"
    }
    }

    最佳答案

    测试用例
    如您所见,您传递了不包含订单的空数组

    test("mock fetch call, empty responce from db should return no data", 
    async () => {
    const fakeResponse = []; <-- empty array which does not contain orders
    const userId = "1234567";

    jest.spyOn(window, "fetch").mockImplementation(() => {
    const fetchResponse = {
    json: () => Promise.resolve(fakeResponse),
    };
    return Promise.resolve(fetchResponse);
    });

    await act(async () => {
    render(<WelcomePage location={userId} />, container);
    });

    expect(container.innerHTML).toContain("no data");

    window.fetch.mockRestore();
    }
    );
    因为当它试图访问 undefinedundefined 没有 map 功能的订单时数据为空
    {data.orders.map((order, index) => ( <-- problems here
    <ul className="orderBox" key={order.toString()+index}>
    <li className="orderLink">
    <Link
    to={{
    pathname: "/OrderDetails",
    state: {
    orderNumber: order.rollNumber,
    userID: this.state.userID,
    },
    }}
    >
    Order number: {order.rollNumber}
    </Link>
    </li>
    <li> Customer name: {order.customerFullName}</li>
    </ul>
    ))}
    你可以像这样改变它:
    {data && data.orders && data.orders.map((order, index) => ( <-- changes
    <ul className="orderBox" key={order.toString()+index}>
    <li className="orderLink">
    <Link
    to={{
    pathname: "/OrderDetails",
    state: {
    orderNumber: order.rollNumber,
    userID: this.state.userID,
    },
    }}
    >
    Order number: {order.rollNumber}
    </Link>
    </li>
    <li> Customer name: {order.customerFullName}</li>
    </ul>
    ))}
    注意:
  • 当您将 fakeResponse 作为数组传递时,您需要将 setState 中的 fetch 中的 WelcomePage.js 更新为

  • if (data && data[0] && data[0]['data']) {
    this.setState({
    data: data[0]['data'], <-- changes
    isLoading: false,
    });
    }
  • 或将 fakeResponse 更改为:

  • const fakeResponse = {
    data: {
    userId: 1234567,
    userForename: "Joe",
    userSurname: "Bloggs",
    orders: [
    {
    orderNumber: 10000000001,
    customerFullName: "Mrs Joes Bloggs",
    userId: 1234567
    },
    ]
    }
    };
    将状态设置为:
    if (data && data['data']) {
    this.setState({
    data: data['data'], <-- changes
    isLoading: false,
    });
    }
    以及检查数据是否为空的条件:
    if (Object.keys(data).length === 0) {
    return <p> no data found</p>;
    }

    关于reactjs - 如何在我的 react 测试中模拟状态和数据的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65307960/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com