使用 Jest 测试 Recharts LineChart 的方法

如何解决使用 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.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?