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);
});
但即使在console.log
之后加入history.listen(location => {
我也没有达到我的history.listen
。所以我很好奇我做错了什么
我也尝试将spyOn
添加到history.listen
,但是很想知道这个特定测试的最佳实践是什么
如果你模拟history.listen
,你可以获得你的组件传递给它的回调。
然后,您可以直接调用回调以验证您的组件是否正确响应。
这是一个完整的工作示例:
history.js
import { createBrowserHistory } from 'history';
export default createBrowserHistory();
code.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; }
}
code.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!
})
我最终做的就是这样。在第一个挂载它返回/
,在第二个挂载它返回/second
并从那里它回到默认状态0(/
)
jest.mock('./history', () => ({
listen: jest
.fn()
.mockImplementationOnce(cb => {
cb({ pathname: '/' });
})
.mockImplementationOnce(cb => {
cb({ pathname: '/second' });
}),
}));
和测试本身(在1个单一测试中测试/second
和/
)
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);
});
但是为了让我最初问过的测试工作就足够了:
jest.mock('./history', () => ({
listen: cb => {
cb({ pathname: '/second' });
},
}));
我只是在嘲笑时不得不通过一个回调,所以接近我以前的,但有一些配对设法让它工作:)
希望它有意义,并将在未来帮助某人