Reactjs 如何使用react测试库模拟ResizeObserver在单元测试中工作

Reactjs 如何使用react测试库模拟ResizeObserver在单元测试中工作,reactjs,unit-testing,jestjs,react-testing-library,window-resize,Reactjs,Unit Testing,Jestjs,React Testing Library,Window Resize,如果有人能提供帮助,我有一个自定义挂钩,它使用ResizeObserver更改组件的宽度。我的问题是,当我运行单元测试时,它会中断所有测试,并且查看快照时,它不会呈现dom中的所有元素。在我实现ResizeObserver之前,它一直在工作。有人知道我是不是在开玩笑。嘲笑ResizeObserver不定义。或其他建议 import * as React from 'react'; import ResizeObserver from 'resize-observer-polyfill'; co

如果有人能提供帮助,我有一个自定义挂钩,它使用ResizeObserver更改组件的宽度。我的问题是,当我运行单元测试时,它会中断所有测试,并且查看快照时,它不会呈现dom中的所有元素。在我实现ResizeObserver之前,它一直在工作。有人知道我是不是在开玩笑。嘲笑ResizeObserver不定义。或其他建议

import * as React from 'react';
import ResizeObserver from 'resize-observer-polyfill';

const useResizeObserver = (ref: { current: any }) => {
    const [dimensions, setDimensions] = React.useState<DOMRectReadOnly>();
    React.useEffect(() => {
        const observeTarget = ref.current;
        const resizeObserver = new ResizeObserver((entries) => {
            entries.forEach((entry) => {
                setDimensions(entry.contentRect);
            });
        });
        resizeObserver.observe(observeTarget);
        return () => {
            resizeObserver.unobserve(observeTarget);
        };
    }, [ref]);
    return dimensions;
};

export default useResizeObserver;



import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';

import mockFetchProfileActivity from '../../../services/mocks/fetch-profile-activity';
import BarChart from './BarChart';

const component = <BarChart userActivity={mockFetchProfileActivity} />;

describe('Render barElement Chart component', () => {
    const observers: any[] = [];
    let resizeHandler: (observers: any[]) => void;
    (window as any).ResizeObserver = (e: any) => {
        resizeHandler = e;

        return {
            observe(element: any) {
                observers.push(element);
            },
            unobserve(element: any) {
                const i = observers.indexOf(element);
                if (i !== -1) {
                    observers.splice(i, 1);
                }
            }
        };
    };

    it('Matches the snapshot', () => {
        // resizeHandler(observers);
        const container = render(component);
        expect(container).toMatchSnapshot();
    });

    it('when clicking on a chart barElement drilldown "challenges" are shown', async () => {
        // arrange
        const componentRender = render(component);
        waitFor(() => resizeHandler(observers));

        // act
        const barElement = componentRender.container.querySelector('svg rect');

        if (barElement) userEvent.click(barElement);

        // assert
        expect(screen.getByText('Challenge 1')).toBeInTheDocument();
    });
});
import*as React from'React';
从“resize observer polyfill”导入ResizeObserver;
const useResizeObserver=(ref:{current:any})=>{
const[dimensions,setDimensions]=React.useState();
React.useffect(()=>{
const observeTarget=参考电流;
const resizeObserver=新的resizeObserver((条目)=>{
条目。forEach((条目)=>{
setDimensions(entry.contentRect);
});
});
resizeObserver.observed(observeTarget);
return()=>{
resizeObserver.unobserve(observeTarget);
};
},[ref]);
返回维度;
};
导出默认useResizeObserver;
从'@testing library/react'导入{render,screen,waitFor};
从“@testing library/user event”导入userEvent;
从“React”导入React;
从“../../../services/mocks/fetch profile activity”导入mockFetchProfileActivity;
从“/BarChart”导入条形图;
常数分量=;
描述('Render barElement图表组件',()=>{
常量观察者:任意[]=[];
让resizeHandler:(观察员:any[])=>void;
(任何窗口)。ResizeObserver=(e:any)=>{
resizeHandler=e;
返回{
观察(要素:任何){
观察员:推动(要素);
},
不可观测(要素:任何){
常数i=观察者。indexOf(元素);
如果(i!==-1){
观察者:拼接(i,1);
}
}
};
};
它('与快照匹配',()=>{
//resizeHandler(观察员);
常量容器=渲染(组件);
expect(container.toMatchSnapshot();
});
它('单击图表时,将显示“挑战”,异步()=>{
//安排
常量componentRender=呈现(组件);
waitFor(()=>resizeHandler(观察员));
//表演
const barElement=componentRender.container.querySelector('svg rect');
if(barElement)userEvent.单击(barElement);
//断言
expect(screen.getByText('Challenge 1')).toBeInTheDocument();
});
});

模拟ResizeObserver:

class ResizeObserver{
遵守{
//无所事事
}
不受欢迎的{
//无所事事
}
}
window.ResizeObserver=ResizeObserver;
导出默认的ResizeObserver;
sample.test.js

从“/”导入ResizeObserver\uuuuuuu mocks\uuuuuu/ResizeObserver';
从“示例”导入模块;
描述('模块',()=>{
它('返回ResizeObserver'的实例,()=>{
//执行使用“调整大小”观察者的操作
//注意:实际的observe处理程序无论如何都不会在jsdom中调用,因为不会触发resize。
//例如。
期望(module.somethingtatreturnareference to resize observer).toBeInstanceOf(ResizeObserver);
});
});

我在使用Create React应用程序设置时遇到了类似的问题

如果是这样,您可以在根目录中创建一个名为
setupTest.js
的文件,并添加以下代码:

  import '@testing-library/jest-dom/extend-expect';
  import 'jest-extended';
    
  jest.mock('./hooks/useResizeObserver', () => () => ({
    __esModule: true,
    default: jest.fn().mockImplementation(() => ({
        observe: jest.fn(),
        unobserve: jest.fn(),
        disconnect: jest.fn(),
    })),
  }));

您可以找到更多信息来配置Create React App和ResizeObserver API的测试环境。我选择将polyfill添加为开发人员依赖项,并将以下行添加到setupTests.js/ts:

global.ResizeObserver = require('resize-observer-polyfill')

这看起来很好,唯一的问题是我有一个错误,你真的有这个工作吗?这是我的错误<代码>属性“ResizeObserver”在类型“Global&typeof globalThis”上不存在。您好,对我来说是的,工作正常。如果删除代码,则会出现此错误
此浏览器不支持立即调整大小。见:https://github.com/react-spring/react-use-measure/#resize-观察者多边形填充
。你把塑料袋取下来了吗?与上面的代码一样,您不需要它。如果是这样的话,可能是版本问题。我使用的是react scripts 4.0.0。很抱歉,我忘了提到我得到的错误(如果我删除resize observer模拟)来自我在项目中使用的库(@visx/tooltip)。在您的情况下,错误可能会有所不同,因为您使用的是不同的库。我没有使用任何库,只是自定义挂钩中的resizeObserver API,因为使用库是不必要的。我使用的是react scripts 4.0.1,但错误更多的是typescript错误,而不是浏览器错误。对不起,上面提出的解决方案仅适用于Javascript。我刚刚找到了一个答案,如果改为
global.ResizeObserver=resizeObserverMock
添加
常量globalAny:any=global;globalAny.ResizeObserver=resizeObserverMock。让我知道这是否有效,我将编辑我的答案,以及如何测试resizeObserver回调中发生的事情?例如,我对HTML元素样式进行了一些更改,需要进行测试。怎么做?非常圆滑,而且工作得很好。我喜欢!要使您的类型很好地匹配,请将其替换为等效的
import
,并将其分配到下一行。