最近写单元测试的时候遇见了一些问题,当我使用使用jest测React. useRef,  React. useEffect时,总是测不到,

然后我去查阅了一下官方文档,它推荐了使用下面这个库

@testing-library/react

我来试了哈,还是不得行,于是根据这个库我在npm里头找到了相关的库,就是下面这个,专门用来测Hook的   @testing-library/react-hooks

 

下面开始示范我的用法,如有不对请稍加修改

这是我的组件BarChart

注意: handleSortByReject 是一个处理函数,我没有把代码贴出来,可以忽略掉这个方法
( 节省时间小tips ,主要关注63-75行的内容,目的是测React.useRef和React.useEffect )
 

  1 import * as React from "react";
2 import {Chart} from "react-chartjs-2";
3 import {Chart as ChartJS, Title, Tooltip, Legend, CategoryScale, BarController, BarElement} from "chart.js";
4 import {IChartDataList} from "./IChartDataList";
5 import {ILinkPosition} from "./common";
6 import {ILink} from "./ILink";
7 import {IDatasetWithDetectionId} from "./IDatasetWithDetectionId";
8 import {ItemWithLoading} from "./ItemWithLoading";
9
10 // Register the elements to display ChartJs. Enables tree-shaking reducing bundle size.
11 // See https://www.chartjs.org/docs/latest/getting-started/integration.html#bundlers-webpack-rollup-etc
12 ChartJS.register(Title, Tooltip, Legend, CategoryScale, BarController, BarElement);
13
14 export interface ISum {
15 subscript: number;
16 totalReject: number[];
17 label: string;
18 sumOfTotalReject?: number;
19 }
20
21 export interface IBarChartProps {
22 /** The state of showing loading icon while sending request */
23 showLoading: boolean;
24 /** height of chart */
25 chartHeight: number;
26 /** current bar data */
27 itemData: IChartDataList;
28 /** sort data by label or total reject, if true, sort by total reject */
29 sortByReject: boolean;
30 }
31
32 export const BarChart: React.FC<IBarChartProps> = (props: IBarChartProps) => {
33 const chartRef = React.useRef<ChartJS>(null);
34
35 /**
36 * @returns options property or bar chart
37 */
38 const getOptionBarChart = (titleKey?: string) => {
39 return {
40 maintainAspectRatio: false,
41 scales: {
42 x: {
43 stacked: true,
44 },
45 y: {
46 stacked: true,
47 },
48 },
49 plugins: {
50 title: {
51 display: true,
52 text: titleKey,
53 },
54 },
55 };
56 };
57
58 /**
59 * use official function to update chart, more detail you can see
60 * 1. [update.html](https://www.chartjs.org/docs/latest/developers/updates.html)
61 * 2. [chartRef-demo](https://react-chartjs-2.netlify.app/examples/chart-ref/)
62 */
63 const updateChartData = (chart) => {
64 if (chart.data !== null && chart.data !== undefined) {
65 chart = handleSortByReject(chart);
66 chart.update();
67 }
68 };
69
70 React.useEffect(() => {
71 const chart = chartRef.current;
72 if (chart !== null) {
73 updateChartData(chart);
74 }
75 }, [props.sortByReject, props.itemData.chartData.labels, props.showLoading, props.chartHeight]);
76
77 return (
78 <>
79 {/* * before get response of backend, show loading
80 * if backend return empty list, show 'no data'
81 * otherwise, render bar chart */}
82 <ItemWithLoading
83 height={props.chartHeight}
84 showLoading={props.showLoading}
85 ele={
86 props.itemData.chartData !== undefined &&
87 props.itemData.chartData.labels &&
88 props.itemData.chartData.labels.length !== 0 &&
89 props.itemData.chartData.datasets.length !== 0 && (
90 /** about ref of bar chart, more detail you can see
91 * [chartRef-demo](https://react-chartjs-2.netlify.app/examples/chart-ref/)
92 */
93 <Chart
94 type="bar"
95 ref={chartRef}
96 height={props.chartHeight}
97 data={props.itemData.chartData}
98 options={getOptionBarChart(props.itemData.titleKey)}
99 />
100 )
101 }
102 />
103 </>
104 );
105 };

BarChart

这是我的组件ItemWithLoading

注意:(节省时间小tips, 可以不关注这个组件)

 1 import * as React from "react";
2 import {AppContext} from "../app/IAppContext";
3 import {Loading} from "../app/Loading";
4 import "../public/style/datalight/ItemWithLoading.scss";
5
6 export interface IItemWithLoadingProps {
7 height: number;
8 /** if true, show loading icon */
9 showLoading: boolean;
10 ele?: JSX.Element | boolean;
11 }
12
13 /** render no data */
14 export const ItemWithLoading: React.FC<IItemWithLoadingProps> = (props: IItemWithLoadingProps) => (
15 // before render element, show loading
16 <AppContext.Consumer>
17 {(ctx) =>
18 props.showLoading ? (
19 <Loading />
20 ) : props.ele ? (
21 props.ele
22 ) : (
23 // if ele not available, show 'no data'
24 <div className="tes-datalight-noData" style={{height: props.height}}>
25 {ctx.translator.translate("tes_fe_gallery_filter_nodata")}
26 </div>
27 )
28 }
29 </AppContext.Consumer>
30 );

这是测试

注意: 前面三个测试采用了react-test-renderer库的create方法来测渲染
第四个测试采用了renderHook方法来测update方法有没有被调用,配合jest.spyOn和jest.fn方法
(节省时间小tips, 主要关注第四个测试 )

 1 import * as React from "react";
2 import * as TypeMoq from "typemoq";
3 import {describe, expect, it, jest} from "@jest/globals";
4 import {ActiveElement, ChartEvent} from "chart.js";
5 import {hotChartData, hotData, mcalMultiChartData, mxChartData, mxData} from "./panel2MockData";
6 import {create} from "react-test-renderer";
7 import {IChartDataList} from "../../datalight/IChartDataList";
8 import {ILinkPosition} from "../../datalight/common";
9 import {ILink} from "../../datalight/ILink";
10 import {BarChart, IBarChartProps} from "../../datalight/BarChart";
11 import {ItemWithLoading} from "../../datalight/ItemWithLoading";
12 import {Chart} from "react-chartjs-2";
13 import {renderHook} from "@testing-library/react-hooks";
14
15 // define props of bar chart
16 const barChartProps: IBarChartProps = {
17 showLoading: true,
18 chartHeight: 300,
19 itemData: mxData,
20 sortByReject: true,
21 };
22
23 /**
24 *
25 * @param height height of chart
26 * @param sortByReject true means sort by total reject. false means sort by label
27 * @returns render component with given property
28 */
29 const renderFrame = (height?: number, sortByReject = false, chartData?: IChartDataList, showLoading = false) => (
30 <BarChart
31 showLoading={showLoading ? showLoading : false}
32 chartHeight={height ? height : 320}
33 itemData={chartData ? chartData : hotData}
34 sortByReject={sortByReject}
35 />
36 );
37
38 describe("render bar chart", () => {
39 it("bar height depend on props 'chartHeight'", () => {
40 const chartHeight = 200;
41 const wrappers = create(renderFrame(chartHeight, false));
42 expect(wrappers.root.findByType(ItemWithLoading).props.height).toBe(chartHeight);
43 wrappers.unmount();
44 });
45
46 it("bar showLoading depend on props 'showLoading'", () => {
47 // render component with property 'showLoading' as true
48 const wrapper = create(renderFrame(undefined, undefined, undefined, true));
49 expect(wrapper.root.findByType(ItemWithLoading).props.showLoading).toBeTruthy();
50 wrapper.unmount();
51 });
52
53 it("when props data is empty", () => {
54 const emptyData: IChartDataList = {
55 titleKey: "empty list",
56 detectionArr: [],
57 chartData: {labels: [], datasets: []},
58 };
59 // render component with empty data
60 const frame = create(renderFrame(undefined, undefined, emptyData));
61 expect(frame.root.findByType(ItemWithLoading).props.ele).toBeFalsy();
62 frame.unmount();
63 });
64
65
66 it("when props 'sortByReject' is false, test render hot chart", () => {
67 const newRef = {
68 current: {
69 update: jest.fn(),
70 // hot data has one items
71 data: hotChartData,
72 },
73 };
74 jest.spyOn(React, "useRef").mockReturnValueOnce(newRef);
75 /** render hooks
76 * more detail you can see [react-hooks-testing](https://react-hooks-testing-library.com/)
77 */
78 renderHook(() => BarChart(barChartProps));
79 expect(newRef.current.update).toHaveBeenCalledTimes(1);
80 });
81 });

BarChart.test.tsx

使用官方推荐的库来测react hook组件的更多相关文章

  1. SVN库迁移整理方法----官方推荐方式

    以下是subversion官方推荐的备份方式. 关闭所有运行的进程,并确认没有程序在访问存储库(如 httpd.svnserve 或本地用户在直接访问). 备份svn存储库 #压缩备份 svnadmi ...

  2. 【译】值得推荐的十大React Hook 库

    十大React Hook库 原文地址:https://dev.to/bornfightcompany/top-10-react-hook-libraries-4065 原文作者:Juraj Pavlo ...

  3. 从零搭建react+ts组件库(封装antd)

    为什么会有这样一篇文章?因为网上的教程/示例只说了怎么做,没有系统详细的介绍引入这些依赖.为什么要这样配置,甚至有些文章还是错的!迫于技术洁癖,我希望更多的开发小伙伴能够真正的理解一个项目搭建各个方面 ...

  4. beeshell —— 开源的 React Native 组件库

    介绍 beeshell 是一个 React Native 应用的基础组件库,基于 0.53.3 版本,提供一整套开箱即用的高质量组件,包含 JavaScript(以下简称 JS)组件和复合组件(包含 ...

  5. Hystrix已经停止开发,官方推荐替代项目Resilience4j

    随着微服务的流行,熔断作为其中一项很重要的技术也广为人知.当微服务的运行质量低于某个临界值时,启动熔断机制,暂停微服务调用一段时间,以保障后端的微服务不会因为持续过负荷而宕机.本文介绍了新一代熔断器R ...

  6. 使用.NET Core中创建Windows服务(一) - 使用官方推荐方式

    原文:Creating Windows Services In .NET Core – Part 1 – The "Microsoft" Way 作者:Dotnet Core Tu ...

  7. EF框架访问access数据库入门(后附官方推荐“驱动”版本)

    vs2017调试通过. 1.添加需要的provider,有点添加驱动的意思.右击项目,NUGET “浏览”,“JetEntityFrameworkProvider”,安装,如图 完成后配置文件(控制台 ...

  8. 使用.NET Core创建Windows服务(一) - 使用官方推荐方式

    原文:使用.NET Core创建Windows服务(一) - 使用官方推荐方式 原文:Creating Windows Services In .NET Core – Part 1 – The &qu ...

  9. 一年时间,Pipenv就成为Python官方推荐的顶级工具?

    Pipenv是Kenneth Reitz在一年多前创建的“面向程序员的Python开发工作流程”,现在已成为管理软件包依赖关系的Python官方推荐资源. Python软件包安装管理的简要历史 为了正 ...

  10. [Android Pro] Android 官方推荐 : DialogFragment 创建对话框

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/37815413 1. 概述 DialogFragment在android 3.0时 ...

随机推荐

  1. mysql 清空数据表id 重1开始 帝国cms清空数据表id 重1开始

    alter table phome_ecms_news auto_increment=1; alter table phome_ecms_news_check auto_increment=1; al ...

  2. MySQL中binlog备份脚本分享

    关于MySQL的二进制日志(binlog),我们都知道二进制日志(binlog)非常重要,尤其当你需要point to point灾难恢复的时侯,所以我们要对其进行备份.关于二进制日志(binlog) ...

  3. 3385. 【NOIP2013模拟】黑魔法师之门

    3385. [NOIP2013模拟]黑魔法师之门 题目大意: 做法: 代码: 题目大意: 给你一个无向无权图,每次询问加入一条边问你图中每个点的度数大于零且都是偶数的子图的个数对1000000009取 ...

  4. 关于spring嵌套事务,我发现网上好多热门文章持续性地以讹传讹

    事情起因是,摸鱼的时候在某平台刷到一篇spring事务相关的博文,文章最后贴了一张图.里面关于嵌套事务的表述明显是错误的. 更奇怪的是,这张图有点印象.在必应搜索关键词PROPAGATION_NEST ...

  5. java无效发源版本xx

    这三个地方统一一下 就可以解决了

  6. VUE的路由懒加载及组件懒加载

    一,为什么要使用路由懒加载 为给客户更好的客户体验,首屏组件加载速度更快一些,解决白屏问题 二,懒加载简单来说就是延迟加载或按需加载,即在需要的时候的时候进行加载 三,常用的懒加载方式有两种:即使用v ...

  7. 基于ChatGPT用AI实现自然对话

    1.概述 ChatGPT是当前自然语言处理领域的重要进展之一,通过预训练和微调的方式,ChatGPT可以生成高质量的文本,可应用于多种场景,如智能客服.聊天机器人.语音助手等.本文将详细介绍ChatG ...

  8. Stream方法的介绍

    文章目录 前言 Lambda表达式 格式 函数式接口 Stream的方法介绍 forEach filter collect count sum limit 和skip groupingBy reduc ...

  9. List 集合手动分页的方法总结

    前言 在工作中难免会遇到,将组装的集合数据进行分页处理,现在我将自己手动分页的三种方法进行总结,有不对的地方敬请大家批评指正! 一.数据准备 // 当前页 int pageIndex = 1; // ...

  10. pytorch学习笔记——timm库

    当使用ChatGPT帮我们工作的时候,确实很大一部分人就会失业,当然也有很大一部分人收益其中.我今天继续使用其帮我了解新的内容,也就是timm库.毫不夸张的说,Chat GPT比百分之80的博客讲的更 ...