Reactjs 在没有动作分派的情况下测试连接的功能组件

Reactjs 在没有动作分派的情况下测试连接的功能组件,reactjs,jestjs,enzyme,Reactjs,Jestjs,Enzyme,我有一个连接的组件,它从Redux存储中获取数据,因此基本上该组件呈现数据,而不需要分派任何操作。我正在使用antd渲染表,以便设置 垂直高度我正在计算高度并传递到ref。此外,我正在为这个示例应用程序使用样式化组件 如何使用Jest和酶进行测试。大多数文章和资料都显示了发送按钮操作和获取数据 请参阅下面的组件 table.js import React, { useState, useEffect, useRef, useLayoutEffect } from "react"

我有一个连接的组件,它从Redux存储中获取数据,因此基本上该组件呈现数据,而不需要分派任何操作。我正在使用antd渲染表,以便设置 垂直高度我正在计算高度并传递到ref。此外,我正在为这个示例应用程序使用样式化组件

如何使用Jest和酶进行测试。大多数文章和资料都显示了发送按钮操作和获取数据

请参阅下面的组件

table.js

import React, { useState, useEffect, useRef, useLayoutEffect } from "react";
import { Table, Alert, Icon } from "antd";
import { connect } from "react-redux";

import constants from "../constants";
import helpers from "../helpers";
import Style from "./style";
import hooks from "../hooks";
import Icon from "../DisabledIcon";

const {
    column_headings: { top_view, front_view },
    unique_keys: { TOP_VIEW },
} = constants;
const { transformRowData } = helpers;

const { TableContainer } = Style;

const { useWindowSize } = hooks;

const Table = props => {
    const {
        isTableDataLoading,
        tableData,
        selectedView,
        headerHeight,
        isTableError,
        tableErrorMessage,
    } = props;
    const [formattedTableData, setFormattedTableData] = useState([]);
    const [columnHeadings, setColumnHeadings] = useState([]);

    const tableRef = useRef(null);
    const size = useWindowSize();
    const [tableHeight, setTableHeight] = useState(118);

    useEffect(() => {
        if (tableData && tableRef.current) {
            let tableHead = document.querySelector(
                `.${tableRef.current.classList[0]} table > thead`
            );
            const reducedPixel = tableHead.offsetHeight + headerHeight;
            setTableHeight(reducedPixel);
        }
    }, [size, tableData, headerHeight]);

    useEffect(() => {
        if (tableData) {
            let columnTitlesList = selectedView === TOP_VIEW ? top_view : front_view;
            columnTitlesList = columnTitlesList.map(colTitle => {
                if (colTitle.key === "disabled") {
                    return {
                        ...colTitle,
                        render: (text, data) => {
                            return <Icon component={text && Icon} />;
                        },
                    };
                }
                return colTitle;
            });
            setColumnHeadings(columnTitlesList);
            const transformedTableData = transformRowData(tableData.list, columnTitlesList);
            setFormattedTableData(transformedTableData);
        }
    }, [tableData]);

    return (
        <>
            {isTableError ? (
                <Alert
                    message={<p style={{ textAlign: "center" }}>{tableErrorMessage}</p>}
                    type="error"
                />
            ) : (
                <TableContainer ref={tableRef}>
                    <Table
                        columns={columnHeadings}
                        rowClassName={record => !record.isEnabled && "disabled-row"}
                        dataSource={formattedTableData}
                        pagination={false}
                        scroll={{ y: `calc(100vh - ${tableHeight}px)` }}
                        loading={isTableDataLoading}
                    />
                </TableContainer>
            )}
        </>
    );
};

const mapStateToProps = ({ tableState }) => {
    return {
        isTableDataLoading: tableState.isLoading,
        isTableError: tableState.isError,
        tableErrorMessage: tableState.errorMessage,
        tableData: tableState.payload,
        selectedView: tableState.view,
    };
};

export default connect(mapStateToProps, null)(Table);
import React from "react";
import { shallow } from "enzyme";
import configureStore from "redux-mock-store";
import constants from "../constants";
import Table from "../Table";
import { Provider } from "react-redux";

const mockStore = configureStore([]);
const {
    unique_keys: { TOP_VIEW },
} = constants;

describe("Table", () => {
    let store;
    let component;
    beforeEach(() => {
        store = mockStore({
            isLoading: false,
            isError: false,
            errorMessage: null,
            payload: null,
            selectedView: TOP_VIEW,
        });
        component = shallow(
            <Provider store={store}>
                <Table />
            </Provider>
        );
    });

    it("should render the component", () => {
        expect(component).toMatchSnapshot();
    });
});
import React,{useState,useffect,useRef,useLayoutEffect}来自“React”;
从“antd”导入{表、警报、图标};
从“react redux”导入{connect};
从“./常量”导入常量;
从“./helpers”导入帮助程序;
从“/Style”导入样式;
从“./hooks”导入钩子;
从“./DisabledIcon”导入图标;
常数{
列标题:{顶视图,前视图},
唯一的_键:{TOP_VIEW},
}=常数;
const{transformRowData}=助手;
const{TableContainer}=Style;
const{useWindowsSize}=hooks;
const Table=props=>{
常数{
isTableDataLoading,
表格数据,
selectedView,
头球,
我的错误,
tableErrorMessage,
}=道具;
const[formattedTableData,setFormattedTableData]=useState([]);
const[columnHeadings,setColumnHeadings]=useState([]);
const tableRef=useRef(null);
常量大小=UseWindowsSize();
const[tableHeight,setTableHeight]=useState(118);
useffect(()=>{
if(tableData和tableRef.current){
让tableHead=document.querySelector(
`.${tableRef.current.classList[0]}table>thead`
);
const reducedPixel=桌面。偏移视线+桌面高度;
可设置高度(减少像素);
}
},[尺寸、表格数据、人头高度];
useffect(()=>{
if(表格数据){
让ColumnTitleList=selectedView==顶视图?顶视图:前视图;
ColumnTitleList=ColumnTitleList.map(colTitle=>{
如果(colTitle.key==“禁用”){
返回{
…colTitle,
呈现:(文本、数据)=>{
返回;
},
};
}
返回colTitle;
});
设置列标题(列标题列表);
const transformedTableData=transformRowData(tableData.list,ColumnTitleList);
setFormattedTableData(transformedTableData);
}
},[tableData]);
返回(
{isTableError(
) : (
!record.isEnabled&“已禁用行”}
数据源={formattedTableData}
分页={false}
scroll={{y:`calc(100vh-${tableHeight}px)`}
正在加载={isTableDataLoading}
/>
)}
);
};
常量MapStateTops=({tableState})=>{
返回{
isTableDataLoading:tableState.isLoading,
isTableError:tableState.isError,
tableErrorMessage:tableState.errorMessage,
tableData:tableState.payload,
selectedView:tableState.view,
};
};
导出默认连接(mapStateToProps,null)(表);
我已经尝试编写了基本测试,也在configureStore中,因为我使用的是Redux Thunk,所以我应该通过中间件

table.test.js

import React, { useState, useEffect, useRef, useLayoutEffect } from "react";
import { Table, Alert, Icon } from "antd";
import { connect } from "react-redux";

import constants from "../constants";
import helpers from "../helpers";
import Style from "./style";
import hooks from "../hooks";
import Icon from "../DisabledIcon";

const {
    column_headings: { top_view, front_view },
    unique_keys: { TOP_VIEW },
} = constants;
const { transformRowData } = helpers;

const { TableContainer } = Style;

const { useWindowSize } = hooks;

const Table = props => {
    const {
        isTableDataLoading,
        tableData,
        selectedView,
        headerHeight,
        isTableError,
        tableErrorMessage,
    } = props;
    const [formattedTableData, setFormattedTableData] = useState([]);
    const [columnHeadings, setColumnHeadings] = useState([]);

    const tableRef = useRef(null);
    const size = useWindowSize();
    const [tableHeight, setTableHeight] = useState(118);

    useEffect(() => {
        if (tableData && tableRef.current) {
            let tableHead = document.querySelector(
                `.${tableRef.current.classList[0]} table > thead`
            );
            const reducedPixel = tableHead.offsetHeight + headerHeight;
            setTableHeight(reducedPixel);
        }
    }, [size, tableData, headerHeight]);

    useEffect(() => {
        if (tableData) {
            let columnTitlesList = selectedView === TOP_VIEW ? top_view : front_view;
            columnTitlesList = columnTitlesList.map(colTitle => {
                if (colTitle.key === "disabled") {
                    return {
                        ...colTitle,
                        render: (text, data) => {
                            return <Icon component={text && Icon} />;
                        },
                    };
                }
                return colTitle;
            });
            setColumnHeadings(columnTitlesList);
            const transformedTableData = transformRowData(tableData.list, columnTitlesList);
            setFormattedTableData(transformedTableData);
        }
    }, [tableData]);

    return (
        <>
            {isTableError ? (
                <Alert
                    message={<p style={{ textAlign: "center" }}>{tableErrorMessage}</p>}
                    type="error"
                />
            ) : (
                <TableContainer ref={tableRef}>
                    <Table
                        columns={columnHeadings}
                        rowClassName={record => !record.isEnabled && "disabled-row"}
                        dataSource={formattedTableData}
                        pagination={false}
                        scroll={{ y: `calc(100vh - ${tableHeight}px)` }}
                        loading={isTableDataLoading}
                    />
                </TableContainer>
            )}
        </>
    );
};

const mapStateToProps = ({ tableState }) => {
    return {
        isTableDataLoading: tableState.isLoading,
        isTableError: tableState.isError,
        tableErrorMessage: tableState.errorMessage,
        tableData: tableState.payload,
        selectedView: tableState.view,
    };
};

export default connect(mapStateToProps, null)(Table);
import React from "react";
import { shallow } from "enzyme";
import configureStore from "redux-mock-store";
import constants from "../constants";
import Table from "../Table";
import { Provider } from "react-redux";

const mockStore = configureStore([]);
const {
    unique_keys: { TOP_VIEW },
} = constants;

describe("Table", () => {
    let store;
    let component;
    beforeEach(() => {
        store = mockStore({
            isLoading: false,
            isError: false,
            errorMessage: null,
            payload: null,
            selectedView: TOP_VIEW,
        });
        component = shallow(
            <Provider store={store}>
                <Table />
            </Provider>
        );
    });

    it("should render the component", () => {
        expect(component).toMatchSnapshot();
    });
});
从“React”导入React;
从“酶”中导入{shall};
从“redux模拟存储”导入configureStore;
从“./常量”导入常量;
从“./Table”导入表;
从“react redux”导入{Provider};
const mockStore=configureStore([]);
常数{
唯一的_键:{TOP_VIEW},
}=常数;
描述(“表格”,()=>{
让商店;
let组件;
在每个之前(()=>{
商店=模拟商店({
孤岛加载:false,
伊瑟罗:错,
errorMessage:null,
有效载荷:空,
所选视图:俯视图,
});
组件=浅(
);
});
它(“应该呈现组件”,()=>{
expect(component.toMatchSnapshot();
});
});

连接的组件通常通过导出组件的未连接版本并为其编写测试来进行测试。这允许您控制向组件和模拟操作提供哪些数据以及何时提供这些数据。你不必嘲笑商店。有关示例,请参见


但是,请注意,在使用时,带有挂钩的组件更难测试。

感谢您的回复,问题是当我导出组件时,它会抛出一个错误,这就是为什么我也提到了测试用例文件。有没有办法测试一下这个。如果你发现这个问题需要回答,那么当你导出未连接的组件时,它会抛出什么样的错误?@DILEEPTHOMAS你能找到一种方法用useState()钩子测试你连接的组件吗?如果是这样,您可以在这里共享test.js文件吗?谢谢