使用 Jest 测试 Recharts LineChart 的方法

问题描述

我对反应还很陌生,但对玩笑也完全陌生。我正在测试其他人已经开发的 recharts Linechart(我知道,与真正的 TDD 相反)。我正在寻找一种使用以下图表代码方法。我想要做的是模拟数据存储(来自 mainApiResponseReducer)并将其用作数据部分的驱动程序,我还想测试 rechart 的组件和此代码(按钮组件、折线图渲染和工具提示渲染)并有正确的数据,但现在可以跳过 X 轴和 Y 轴和线,最大的问题是图表渲染与数据和工具提示)。最好的方法是什么?考虑到我几乎不知道该去哪里,任何开始的示例代码都值得赞赏:) 谢谢。代码如下:

import React,{ useState } from 'react';
import { makeStyles } from '@material-ui/core/styles';
import { usedispatch,useSelector } from 'react-redux';

import {
    LineChart,Line,XAxis,YAxis,Cartesiangrid,Tooltip,ReferenceLine,ResponsiveContainer
} from 'recharts';
import { object } from 'prop-types';
import styles from '../styles.scss';

const useStyles = makeStyles((theme) => ({
    buttonOff: {
        width: '75px',height: '24px',borderRadius: '50px',margin: '2.5px',color: 'rgba(8,8,59,1)',BoxShadow: ' 0px 0px 0px 0px rgba(8,borderStyle: 'solid',backgroundColor: 'rgba(8,0.1)',opacity: '0.3'
    },buttonRed: {
        width: '75px',borderColor: '#CD2821',color: '#BE1710',backgroundColor: '#FAE9E8'

    },buttonGreen: {
        width: '75px',borderColor: '#288179',color: '#22766F',backgroundColor: '#E9F2F1'

    },buttonBlue: {
        width: '75px',borderColor: '#0E65BC',color: '#0E65BC',backgroundColor: '#E7F1FA'

    }

}));

const CustomTooltip = (props) => {
    const {
        active,label,payload,temp2
    } = props;

    if (active && payload && payload.length) {
        return (
      <div style={{
          backgroundColor: '#16214F',width: '160px',height: '90px',left: '80px',position: 'relative'
      }}
      >
{typeof payload[0] !== 'undefined'
    && <p style={{ color: '#FFFFFF',paddingTop: '0px',fontSize: '15px' }}>{payload[0].payload.fsc_YR_NBR} - WEEK {payload[0].payload.week_NBR}</p>}
          {typeof payload[2] !== 'undefined'
        && (
<div style={{ color: '#FFFFFF',display: 'inline',marginRight: '20px' }}><button style={{
    backgroundColor: payload[2].stroke,width: '25px',height: '7px',borderRadius: '50px'
}} disabled
/>{` ${payload[2].value.toFixed(2)}  `}

</div>
        ) }
        {typeof payload[1] !== 'undefined'
        && (
<div style={{ color: '#FFFFFF',display: 'inline' }}><button style={{
    backgroundColor: payload[1].stroke,borderRadius: '50px'
}} disabled
/>{` ${payload[1].value.toFixed(2)}`}

</div>
        ) }
        {typeof payload[0] !== 'undefined'
        && (
<div style={{ color: '#FFFFFF' }}><button style={{
    backgroundColor: payload[0].stroke,borderRadius: '50px'
}} disabled
/>{` ${payload[0].value.toFixed(2)}`}

</div>
        ) }
      </div>

        );
    }

    return null;
};

const ForecastGraph = () => {
    const dispatch = usedispatch();
    const mainApiResponse = useSelector((state) => state.mainApiResponseReducer);
    const temp2 = [];
    let i; let
        t1 = 1; let pos;
    let max = 10;
    temp2.push({ week: 0 });

    const data = [];
    if (mainApiResponse.data) {
        if (mainApiResponse.data[0]) var flag = mainApiResponse.data[0].fsc_WK_NBR;
        for (let c = 0; c < mainApiResponse.data.length; c++) {
            if (flag === mainApiResponse.data[c].fsc_WK_NBR) data.push(mainApiResponse.data[c]);
            else {
                data.push({ fsc_WK_NBR: flag }); c--;
            }
            if (flag == 52) flag = 0;
            flag++;
        }
        // console.log('d');
        // console.log(data);

        for (i = 0; i < data.length; i++) {
            if (Object.keys(data[i]).length > 3) {
                pos = i;
                break;
            }

            pos = data.length;
        }
        if (data[i - 1]) {
            console.log(data[i - 1].fsc_YR_NBR);
            var cp = 52 * (mainApiResponse.year - data[i - 1].fsc_YR_NBR) + (mainApiResponse.week - data[i - 1].fsc_WK_NBR);
            console.log(`cp= + ${cp}`);
            const wk = data[i - 1].fsc_WK_NBR;
        }

        console.log(pos);
        if ((pos + cp) < 156) {
            for (var j = 0; j < (156 - pos); j++) {
                temp2.push({ fsc_WK_NBR: t1 });
                t1++;
                if (t1 > 52) t1 = 1;
            }
            pos = 156;
        }
        i = 0;
        console.log('a');
        console.log(temp2);
        let m = 0;
        for (m = (pos + cp - 156); m < data.length; m++) {
            if (t1 > 52) { t1 = 1; }
            if (Object.keys(data[m]).length == 3) {
                temp2.push({
                    fsc_WK_NBR: t1,week_NBR: data[m].fsc_WK_NBR,fsc_YR_NBR: data[m].fsc_YR_NBR,sales_UNITS: data[m].sales_UNITS
                });
                t1++;
                if (max < data[m].sales_UNITS) { max = data[m].sales_UNITS; }
            } else if (Object.keys(data[m]).length > 3) break;
            else { temp2.push({ fsc_WK_NBR: t1 }); t1++; }
        }
        for (let q = 0; q < cp - 1; q++) {
            if (t1 > 52) { t1 = 1; }
            temp2.push({ fsc_WK_NBR: t1 });
            t1++;
            m++;
        }

        for (var j = m; j < data.length; j++) {
            if (t1 > 52) { t1 = 1; }i++;
            if (Object.keys(data[j]).length == 4) {
                temp2.push({
                    fsc_WK_NBR: t1,week_NBR: data[j].fsc_WK_NBR,fsc_YR_NBR: data[j].fsc_YR_NBR,forecast_UNITS_BY: data[j].forecast_UNITS_BY,forecast_UNITS_LIFT: data[j].forecast_UNITS_LIFT
                });
                t1++;
                if (max < data[j].forecast_UNITS_BY) { max = data[j].forecast_UNITS_BY; }
            } else { temp2.push({ fsc_WK_NBR: t1 }); t1++; }
        }
        for (let k = i; k < 52; k++) {
            if (t1 > 52) { t1 = 1; }
            temp2.push({ fsc_WK_NBR: t1 });
            t1++;
        }
    }
    console.log('final');
    console.log(temp2);

    const classes = useStyles();
    const [on1,setButton1] = useState(true);
    const [on2,setButton2] = useState(true);
    const [on3,setButton3] = useState(true);

    const handlebutton1 = () => {
        setButton1(!on1);
    };
    const handlebutton2 = () => {
        setButton2(!on2);
    };
    const handlebutton3 = () => {
        setButton3(!on3);
    };
    const formatXAxis = (tickItems) => (tickItems / 13) * 3;

    return (
        <div className={ styles.graphGrid }>
        <center>
          {on1
            && <button className={ classes.buttonRed } onClick={ handlebutton1 }>Sales</button>
          }
          {!on1
            && (
            <button className={ classes.buttonOff }
            onClick={ handlebutton1 }
        >Sales
</button>
    )
        }

        {on2
      && <button className={ classes.buttonGreen } onClick={ handlebutton2 }>B2</button>
        }
        {!on2
    && (
<button className={ classes.buttonOff }
    onClick={ handlebutton2 }
>BYD
</button>
    )
        }
                {on3
      && <button className={ classes.buttonBlue } onClick={ handlebutton3 }>B3</button>
        }
        {!on3
    && (
<button className={ classes.buttonOff }
    onClick={ handlebutton3 }
>Lowe's
</button>
    )
        }

    <ResponsiveContainer height="50%" width="99%" aspect={ 4 }>
        <LineChart
            width={ 500 }
            height={ 300 }
            data={ temp2 }
            margin={{
                top: 15,right: 30,left: 20,bottom: 5
            }}
        >
        <Cartesiangrid vertical={ false } opacity="0.4" />
        <XAxis 
            dataKey="fsc_WK_NBR" 
            xAxisId={ 0 } 
            tickFormatter={ formatXAxis } 
            interval={ 12 } 
            tickLine 
            tickMargin={ 5 } />
        <YAxis 
            type="number" 
            domain={ [0,max] } 
            tickCount={ 7 } 
            axisLine={ false } 
            tickLine={ false } />
        <Tooltip 
            offset="1" 
            content={ <CustomTooltip temp2={ temp2 } /> } />
        <ReferenceLine x={ 52 } />
        <ReferenceLine x={ 104 } />
        <ReferenceLine x={ 156 } stroke="black" />

        {on1 && temp2.length
        && <Line type="monotone" dataKey="sales_UNITS" stroke="red" isAnimationActive={ false } dot={{ r: 0 }} />// red
        }

        {on2 && temp2.length
        && <Line type="monotone" dataKey="forecast_UNITS_BY" stroke="green" isAnimationActive={ false } dot={{ r: 0 }} /> // green
        }

        {on3 && temp2.length
        && <Line type="monotone" dataKey="forecast_UNITS_LIFT" stroke="blue" isAnimationActive={ false } dot={{ r: 0 }} /> // blue
        }

        </LineChart>
    </ResponsiveContainer>
    </center>
    </div>
  );
};

export default ForecastGraph;

我只是想开始看看我是否可以渲染这个 ForecastGraph 组件。下面是我的代码,但我收到以下错误,并且不确定如何处理元素类型:

ForecastGraph.test.jsx:

/**
 * @jest-environment jsdom
 */
 import React from 'react';
 import { mount } from 'enzyme';
 import {ForecastGraph} from '../../../src/common/components/common/ForecastTab/ForecastGraph';
 
 describe('ForecastGraph/>',() => {

    let wrapper;

    // const data = [
    //     {fsc_WK_NBR: 11,fsc_YR_NBR: 2021,sales_UNITS: 160},//     {fsc_WK_NBR: 12,sales_UNITS: 203},//     {fsc_WK_NBR: 13,sales_UNITS: 172},//     {fsc_WK_NBR: 14,sales_UNITS: 170},//     {fsc_WK_NBR: 15,sales_UNITS: 249},//     {fsc_WK_NBR: 16,sales_UNITS: 166},//     {fsc_WK_NBR: 17,sales_UNITS: 108},//     {fsc_WK_NBR: 18,sales_UNITS: 207},//     {fsc_WK_NBR: 19,forecast_UNITS_BY: 153,forecast_UNITS_LIFT:190}
    // ];
 
    it('rendering ForecastGraph Component',() => {
        wrapper = mount(<ForecastGraph/>).toJSON();
        expect(wrapper).toMatchSnapshot();
    });
 });

测试失败控制台日志:

 FAIL  tests/components/ForecastGraph/ForecastGraph.test.jsx
  ForecastGraph/>
    × rendering ForecastGraph Component (138ms)

  ● ForecastGraph/> › rendering ForecastGraph Component

    Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in,or you might have mixed up default and named imports.

    Check the render method of `WrapperComponent`.

      25 |
      26 |     it('rendering ForecastGraph Component',() => {
    > 27 |         wrapper = mount(<ForecastGraph/>).toJSON();
         |                   ^
      28 |         expect(wrapper).toMatchSnapshot();
      29 |     });
      30 |  });

      at createFiberFromTypeAndProps (node_modules/react-dom/cjs/react-dom.development.js:23965:21)
      at Object.<anonymous> (tests/components/ForecastGraph/ForecastGraph.test.jsx:27:19)

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...