无法监视 useWindowSize 属性,因为它不是函数;改为未定义

问题描述 投票:0回答:1

我正在尝试模拟一个函数,以便我可以根据钩子中变量的特定值覆盖分支。

这是我的测试文件

  import React from 'react';
  import { render, screen, fireEvent, act } from '@testing-library/react';
  import userEvent from '@testing-library/user-event';
  import '@testing-library/jest-dom/extend-expect';
  import GamesEngagement from 'pages/Analytics/GamesEngagement';
  import { useGetEngagementInsightsQuery } from 'app/services/analytics';
  import localStorage from 'utils/localStorage';
  import hooks from 'utils/hooks';

  jest.mock('components/Charts', () => {
    return {
      __esModule: true,
      default: () => {
        return <div data-testid='mocked-charts'></div>;
      }
    };
  });

  jest.mock('app/services/analytics', () => ({
    useGetEngagementInsightsQuery: jest.fn()
  }));

  jest.mock('utils/localStorage', () => ({
    getPlatform: jest.fn(),
    getToken: jest.fn()
  }));

  // jest.mock('utils/hooks', () => ({
  //   __esModule: true, // this property makes it work
  //   useWindowSize: () => [500], // Mock implementation of the hook
  // }));


  describe(`GamesEngagement Component`, () => {
    beforeEach(() => {
      useGetEngagementInsightsQuery.mockReturnValue({
        data: [{ mark: 'A', engagementRate: 80 }],

        isFetching: false
      });
    });

    it(`rendered correctly`, () => {
      render(<GamesEngagement />);
      expect(screen.getByText('Games engagement rate')).toBeInTheDocument();
    });
  });

  describe(`GamesEngagement Component`, () => {
    let openWindowSpy;
    beforeEach(() => {
      useGetEngagementInsightsQuery.mockReturnValue({
        isFetching: false
      });

      openWindowSpy = jest.spyOn(window, 'open').mockImplementation(() => {});
    });

    afterEach(() => {
      openWindowSpy.mockRestore();
    });

    it(`rendered correctly`, () => {
      render(<GamesEngagement />);
      expect(screen.getByText('Games engagement rate')).toBeInTheDocument();
    });

    it('should open a specific URL when platform is "teams"', () => {
      localStorage.getPlatform.mockReturnValue('teams');
      const { getByText } = render(<GamesEngagement />);
      fireEvent.click(getByText('Start a game'));
      expect(openWindowSpy).toHaveBeenCalledWith(
        'https://teams.microsoft.com/l/entity/undefined/homeTab',
        '_blank'
      );
    });

    it('should open a different URL when platform is not "teams"', () => {
      localStorage.getPlatform.mockReturnValue('not-teams');
      const { getByText } = render(<GamesEngagement />);
      fireEvent.click(getByText('Start a game'));
      expect(openWindowSpy).toHaveBeenCalledWith(
        `undefined/slack-deeplink?page=gamesPage&key=undefined`,
        '_blank'
      );
    });
  });

  describe(`GamesEngagement Component`, () => {
    beforeEach(() => {
      useGetEngagementInsightsQuery.mockReturnValue({
        data: [{ mark: 'A', engagementRate: 80 }],

        isFetching: true
      });
    });

    it(`rendered correctly`, () => {
      render(<GamesEngagement />);
      expect(screen.getByText('Games engagement rate')).toBeInTheDocument();
    });

    it('width is less than 425', () => {
      jest.spyOn(hooks, 'useWindowSize').mockImplementation(() => ({width: 400, height: 400}))
      
      render(<GamesEngagement />);
      expect(screen.getByTestId('mocked-charts')).toBeInTheDocument();
    })

  });

这是我面临的错误。

 GamesEngagement Component › width is less than 425

    Cannot spy the useWindowSize property because it is not a function; undefined given instead

      102 |
      103 |     it('width is less than 425', () => {
    > 104 |       jest.spyOn(hooks, 'useWindowSize').mockImplementation(() => ({width: 400, height: 400}))
          |            ^
      105 |       
      106 |       render(<GamesEngagement />);
      107 |       expect(screen.getByTestId('mocked-charts')).toBeInTheDocument();

      at ModuleMocker.spyOn (node_modules/jest-mock/build/index.js:798:15)
      at Object.<anonymous> (src/test/pages/Analytics/GamesEngagement/index.test.js:104:12)

useWindowSize 函数使用钩子或宽度。我无法获取它的价值。 这就是它在react文件中的使用方式。

const { width } = useWindowSize();
...more code
 <Charts
          type='line'
          labels={width < 425 ? labels.slice(-5) : labels}
          datasets={[
            {
              data: width < 425 ? data.slice(-5) : data,
              backgroundColor: '#E1DCFF'
            }
          ]}
...more code

这是 useWindowSize 函数本身

function useWindowSize() {
  const [windowSize, setWindowSize] = useState({
    width: undefined,
    height: undefined
  });

  useEffect(() => {
    function handleResize() {
      setWindowSize({
        width: window.innerWidth,
        height: window.innerHeight
      });
    }

    window.addEventListener('resize', handleResize);
    handleResize();

    return () => window.removeEventListener('resize', handleResize);
  }, []);

  return windowSize;
}
export default useWindowSize;

如何正确模拟它以便测试用例通过并增加分支覆盖率?

reactjs testing jestjs mocking
1个回答
0
投票

问题在于您的导入。如果你改变:

  import hooks from 'utils/hooks';

  import * as hooks from 'utils/hooks';

应该可以。

您可以在这些文档中查找导入方式之间的差异:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import

© www.soinside.com 2019 - 2024. All rights reserved.