首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何模拟history.listen?

如何模拟history.listen?
EN

Stack Overflow用户
提问于 2019-04-04 23:56:29
回答 2查看 3K关注 0票数 3

history.js

代码语言:javascript
复制
import { createBrowserHistory } from 'history';

export default createBrowserHistory();

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

代码语言:javascript
复制
import history from './history';

构造函数中的以下内容:

代码语言:javascript
复制
history.listen(location => {
  if (location.pathname === '/second') {
    this.setState({
      pathStep: 1,
    });
  } else if (location.pathname === '/') {
    this.setState({
      pathStep: 0,
    });
  }
});

现在我正在努力为它做一个有效的测试:

代码语言:javascript
复制
    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中,但是非常想知道这个特定测试的最佳实践是什么

EN

回答 2

Stack Overflow用户

发布于 2019-04-06 15:51:30

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

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

下面是一个完整的工作示例:

history.js

代码语言:javascript
复制
import { createBrowserHistory } from 'history';

export default createBrowserHistory();

code.js

代码语言:javascript
复制
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; }
}

code.test.js

代码语言:javascript
复制
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!
})
票数 2
EN

Stack Overflow用户

发布于 2019-04-05 23:19:38

我最终做的就是这样的事情。在第一次挂载时,它返回/,在第二次挂载时,它返回/second,然后从那里返回默认状态0(/)

代码语言:javascript
复制
jest.mock('./history', () => ({
  listen: jest
    .fn()
   .mockImplementationOnce(cb => {
      cb({ pathname: '/' });
    })
    .mockImplementationOnce(cb => {
      cb({ pathname: '/second' });
    }),
}));

以及测试本身(在一个测试中同时测试/second/ )

代码语言:javascript
复制
it('changes pathStep when called', () => {
    expect(component.state().pathStep).toBe(0);

    component = mount(<MyComponent />);

    expect(component.state().pathStep).toBe(1);

    component = mount(<MyComponent />);

    expect(component.state().pathStep).toBe(0);
  });

但要让我最初要求的测试工作,这样的东西就足够了:

代码语言:javascript
复制
jest.mock('./history', () => ({
  listen: cb => {
    cb({ pathname: '/second' });
  },
}));

我只是在模仿时传递了一个回调,非常接近于我以前的回调,但通过一些配对成功地使其工作:)

希望这是有意义的,并将在未来帮助某些人

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55520337

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档