首页 > 解决方案 > 无法收听哈希更改事件去测试组件

问题描述

我有一个功能性的 React 组件,它监听哈希变化并相应地调用一个函数:

const Component: React.FC = () => {

    function handleHashChanged() {
        
    }

    useEffect(() => {
        window.addEventListener('hashchange', handleHashChanged);
        return () => window.removeEventListener('hashchange', handleHashChanged);
    });

};

这可以正常工作,但在运行测试(使用酶)时不能正常工作。我在测试中将组件安装在文档上,但没有运气:

const component = mount(<Component/>, { attachTo: document.body });
window.location.hash = "test";
// handleHashChange not called

标签: javascriptreactjstypescriptjestjsenzyme

解决方案


您可以使用EventTarget.dispatchEvent()来调度HashChangeEvent

例如

index.tsx

import React, { useEffect } from 'react';

export const Component: React.FC = () => {
  function handleHashChanged(event) {
    console.log(event.newURL);
  }

  useEffect(() => {
    window.addEventListener('hashchange', handleHashChanged);
    return () => window.removeEventListener('hashchange', handleHashChanged);
  });

  return <div>a component</div>;
};

index.test.tsx

import { mount } from 'enzyme';
import React from 'react';
import { Component } from './';

describe('67051487', () => {
  it('should pass', () => {
    const addEventListenerSpy = jest.spyOn(window, 'addEventListener');
    const removeEventListenerSpy = jest.spyOn(window, 'removeEventListener');
    const component = mount(<Component />);
    expect(addEventListenerSpy).toBeCalledWith('hashchange', expect.any(Function));
    window.dispatchEvent(
      new HashChangeEvent('hashchange', {
        oldURL: 'http://example.com/index.html#123',
        newURL: 'http://example.com/idnex.html#456',
      })
    );
    component.unmount();
    expect(removeEventListenerSpy).toBeCalledWith('hashchange', expect.any(Function));
    addEventListenerSpy.mockRestore();
    removeEventListenerSpy.mockRestore();
  });
});

测试结果:

 PASS  examples/67051487/index.test.tsx (8.696 s)
  67051487
    ✓ should pass (53 ms)

  console.log
    http://example.com/idnex.html#456

      at handleHashChanged (examples/67051487/index.tsx:5:13)

-----------|---------|----------|---------|---------|-------------------
File       | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-----------|---------|----------|---------|---------|-------------------
All files  |     100 |      100 |     100 |     100 |                   
 index.tsx |     100 |      100 |     100 |     100 |                   
-----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        9.633 s

包版本:

"enzyme": "^3.11.0",
"jest": "^26.6.3",
"react": "^16.14.0",

推荐阅读