react-router - 如何模拟 history.listen?

标签 react-router enzyme browser-history history.js

history.js

import { createBrowserHistory } from 'history';

export default createBrowserHistory();

在我的 .js 中,这就是我使用 history.listen 的方式

import history from './history';

构造函数中的以下内容:

history.listen(location => {
  if (location.pathname === '/second') {
    this.setState({
      pathStep: 1,
    });
  } else if (location.pathname === '/') {
    this.setState({
      pathStep: 0,
    });
  }
});

现在我正在努力对此进行有效测试:

    I tried to do the following:
    jest.mock('./history', () => ({
      listen: () => () => {
        '/second';
      },
    }));

    it('changes activeStep when called', () => {
      expect(component.state().pathStep).toBe(1);
    });

但即使在 history.listen(location => { 之后添加 console.log 我也没有到达我的 history.listen。所以我很好奇我做错了什么

我还尝试将 spyOn 添加到 history.listen,但很想知道这个特定测试的最佳实践是什么

最佳答案

如果您模拟 history.listen,您可以获取组件传递给它的回调

然后,您可以直接调用回调来验证您的组件是否正确响应。

这是一个完整的工作示例:

历史.js

import { createBrowserHistory } from 'history';

export default createBrowserHistory();

代码.js

import * as React from 'react';
import history from './history';

export class SimpleComponent extends React.Component {
  constructor(...args) {
    super(...args);
    this.state = { pathStep: 0 };
  }
  componentDidMount() {
    this.unlisten = history.listen(location => {
      if (location.pathname === '/second') {
        this.setState({
          pathStep: 1,
        });
      } else if (location.pathname === '/') {
        this.setState({
          pathStep: 0,
        });
      }
    });
  }
  componentWillUnmount() {
    this.unlisten();
  }
  render() { return null; }
}

代码.test.js

import * as React from 'react';
import history from './history';
import { mount } from 'enzyme';

import { SimpleComponent } from './code';

test('SimpleComponent', () => {
  const listenMock = jest.spyOn(history, 'listen');
  const unlistenMock = jest.fn();
  listenMock.mockReturnValue(unlistenMock);

  const component = mount(<SimpleComponent />);
  expect(component.state().pathStep).toBe(0);  // Success!

  const callback = listenMock.mock.calls[0][0];  // <= get the callback passed to history.listen

  callback({ pathname: '/second' });
  expect(component.state().pathStep).toBe(1);  // Success!

  callback({ pathname: '/' });
  expect(component.state().pathStep).toBe(0);  // Success!

  component.unmount();
  expect(unlistenMock).toHaveBeenCalled();  // Success!
})

关于react-router - 如何模拟 history.listen?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55520337/

相关文章:

javascript - 保留页面状态以使用浏览器后退按钮重新访问

javascript - 使用 javascript :history. go(-1) 有效,但我丢失了 css 属性和脚本

seo - 当涉及到 History API 时,Google 如何处理内容的索引?

javascript - Express'response.sendFile() 发送未捕获的语法错误 : Unexpected token <

javascript - 使用 react-router,redux 将无法工作

reactjs - 使用 Jest/Enzyme 测试延迟的自定义 React 钩子(Hook)?

reactjs - 如何测试函数是否在功能性 React 组件中调用 onChange?

reactjs - React-Router 中使用的类型/大小写错误

reactjs - 对于带有 React Router 的样式组件,子组件没有 props.theme

javascript - 为什么 JEST 测试中的 getCompulatedStyle() 返回与 Chrome/Firefox DevTools 中的计算样式不同的结果