reactjs - 我如何测试被 withRouter 包裹的 React 组件的回调?
我正在使用 Jest 和 Enzyme 来测试一个用 TypeScript 编写的 React 项目。我有一个组件,它被包装在 React-Router 路由器中,看起来大致如下:
import { SomeButton } from './someButton';
import { RouteComponentProps, withRouter } from 'react-router';
const SomeButtonWithRouter = withRouter<{buttonCallback: () => void}>(SomeButton);
export class SomePage extends React.Component <RouteComponentProps<{}>, {}> {
constructor(props: {}) {
super(props);
this.someCallback = this.someCallback.bind(this);
}
public render() {
return (
<div>
<SomeButtonWithRouter buttonCallback={this.someCallback}/>
</div>
);
}
// This is the callback I want to test:
private someCallback() {
console.log('This is a callback');
}
现在我正在尝试编写一个测试,该测试调用 someCallback,然后进行一些断言。我已经将 SomePage 包装在 MemoryRouter 中,以便能够进行测试:
it('should do something', () => {
const page = mount(<MemoryRouter><SomePage/></MemoryRouter>);
const cb = page.find('SomeButton').prop('buttonCallback'); // <-- this is undefined
});
如评论中所述,不幸的是,当这样访问时,buttonCallback 属性是未定义的。不过,当我输出 page 时,它确实显示已定义:
<withRouter(SomeButton)
onVerified={[Function bound ]}
以及下面的一些行:
<SomeButton
history={ // ...
// ...
onVerified={[Function bound ]}
对于 Enzyme 的 find,SomeButton 和 withRouter(SomeButton) 都不能作为选择器使用。
我不确定为什么会这样;我确实能够通过这种方式访问另一个没有被 withRouter 包裹的子组件的回调。我也不确定我所做的一切是否是正确的做法,所以任何关于更好做法的指点都是欢迎的。
答案#1
咕…像往常一样,一夜的睡眠让我找出了问题——实际上问题并不在这里。如果对任何人有帮助,我会详细说明我犯的错误。
首先,最有用的信息是:const cb=page.find('SomeButton').prop('buttonCallback'); 和 const cb=page.find('withRouter(SomeButton)').prop('buttonCallback'); 都应该可以工作——尽管我会选择前者,因为这样你就不需要了解路由的使用。
其次,我认为它不起作用的原因是因为我试图使用 toJson(page.find('SomeButton').prop('buttonCallback'))(使用 enzyme-to-json)输出结果,而这会把该函数高兴地转换为 undefined。
最后,这也是最愚蠢的事情——我没有看到调用回调的效果,因为……我实际上并没有调用它。我只是将它赋值为 const buttonCallback=page.find...,但接着还必须写 buttonCallback()。哦,还有:我之后的断言里有一个拼写错误。
我知道,很蠢。当你六个月后遇到这个问题时,随便嘲笑我吧。