【问题标题】:How to mock window.location.href with Jest in React?如何在 React 中用 Jest 模拟 window.location.href?
【发布时间】:2020-12-04 03:32:15
【问题描述】:

我正在测试不应该在本地运行并且需要模拟 window.location.href 的功能:

const usePageTracking = (): void => {
  const location = useLocation();

  useEffect(() => {
    if (!window.location.href.includes("localhost")) {
      ReactGA.initialize("UA-000000-01");
      ReactGA.pageview(window.location.pathname + window.location.search);
    }
  }, []);
};

在我的测试中:

describe("usePageTracking", () => {
  it("initializes ReactGA", () => {
    render(<Example />);
    expect(ReactGA.initialize).toHaveBeenCalled();
  });

  it("tracks page view", () => {
    render(<Example />);
    expect(ReactGA.pageview).toHaveBeenCalledWith("/");
  });
});

注意:有一个 related question around Vue,但我不清楚这些解决方案是否也适用于 React(有些只是不起作用)。

【问题讨论】:

    标签: reactjs testing jestjs react-hooks mocking


    【解决方案1】:

    我在 React 16 和 Jest 24 上得到了以下结果。

    describe("usePageTracking", () => {
      let location;
      const mockLocation = new URL("https://example.com");
    
      beforeEach(() => {
        location = window.location;
        mockLocation.replace = jest.fn();
        // You might need to mock other functions as well
        // location.assign = jest.fn();
        // location.reload = jest.fn();
        delete window.location;
        window.location = mockLocation;
      });
    
      afterEach(() => {
        window.location = location;
      });
    
      // ...
    });
    

    另见:

    【讨论】:

      【解决方案2】:

      使用Object.defineProperty()window.location 定义一个getter。

      例如

      usePageTracking.ts:

      import { useEffect } from 'react';
      
      export const usePageTracking = (): void => {
        useEffect(() => {
          console.log(window.location.href);
        }, []);
      };
      

      Example.tsx:

      import React from 'react';
      import { usePageTracking } from './usePageTracking';
      
      export function Example() {
        usePageTracking();
        return <div>example</div>;
      }
      

      Example.test.tsx:

      import React from 'react';
      import { Example } from './Example';
      import { render } from '@testing-library/react';
      
      describe('Example', () => {
        it('should pass', () => {
          Object.defineProperty(window, 'location', {
            get() {
              return { href: 'stackoverflow.com' };
            },
          });
          render(<Example />);
        });
      });
      

      测试结果

       PASS  examples/63409476/Example.test.tsx (11.048 s)
        Example
          ✓ should pass (39 ms)
      
        console.log
          stackoverflow.com
      
            at examples/63409476/usePageTracking.ts:5:13
      
      Test Suites: 1 passed, 1 total
      Tests:       1 passed, 1 total
      Snapshots:   0 total
      Time:        12.768 s
      

      软件包版本:

      "jest": "^26.6.3",
      "ts-jest": "^26.4.4",
      

      jest.config.js:

      module.exports = {
        preset: 'ts-jest/presets/js-with-ts',
      }
      

      【讨论】:

      • Object.defineProperty() 与打字稿完美配合!
      猜你喜欢
      • 2019-05-29
      • 1970-01-01
      • 2017-06-08
      • 2017-08-17
      • 2022-06-28
      • 2020-09-16
      • 1970-01-01
      • 2022-01-19
      • 2011-06-15
      相关资源
      最近更新 更多