在React中,我正在测试子组件内部的按钮单击是否会通过事件冒泡在父组件(onDeleteClick)中调用一个函数。
对于此测试,我使用的是mount
,因为浅层不允许我们在子组件中触发函数。
onDeleteClick
是我要检查是否被调用的函数,它是一个类属性,在这种情况下,它是一个箭头函数。
我正在模拟onDeleteClick函数,并在开始测试时通过Redux Provider
将其传递到我的组件中。
我遇到的问题是,在测试结束时,当我执行检查以查看模拟函数是否被调用时,它返回0。
expect(onDeleteClick.mock.calls.length).toBe(1);
如果将console.log放在onDeleteClick()中,则它是在测试期间输出的,因此我知道实际上是在调用该函数。
我对此进行了相当多的研究,到目前为止还没有任何工作。 一些建议是监视我的模拟函数,然后在包装器上调用forceUpdate,但这没有产生任何积极的结果。
为此,我将Jest
与Enzyme
一起使用。
参考代码:
Parent.js
import { deleteAccount } from '../../actions/profileActions';
import ChildComponent from '../common/ChildComponent';
class ParentComponent extends Component {
onDeleteClick = () => {
console.log('onDeleteClick was executed during this test!')
this.props.deleteAccount();
}
render() {
let dashboardContent;
dashboardContent = (
<div>
<ChildComponent onDelete={this.onDeleteClick} />
</div>
);
return (
<div>
{dashboardContent}
</div>
);
}
}
// propTypes and mapStateToProps removed from this post
export default connect(
mapStateToProps,
{ deleteAccount }
)(ParentComponent);
__ tests __ / ParentComponent.js
import React from 'react';
import { mount } from 'enzyme';
import { BrowserRouter as Router } from 'react-router-dom';
import { Provider } from 'react-redux';
import configureStore from 'redux-mock-store';
import ParentComponent from '../ParentComponent';
import thunk from "redux-thunk";
const mockStore = configureStore([thunk]);
const deleteAccount = jest.fn();
const props = {
deleteAccount
}
const randomTestState = {
// some initial state, not important
};
const randomTestStore = mockStore(randomTestState);
describe('<ParentComponent />', () => {
it(`mounts the ParentComponent component and, when ChildComponent sends onDelete, then deleteAccount function is called once`, () => {
const wrapper = mount(
<Provider store={randomTestStore} props={props}>
<Router >
<ParentComponent />
</Router>
</Provider>
);
// Here, I grab an element in ChildComponent and simulate a click using Enzyme, then the event bubbles up, and deleteAccount() is called in the parent component.
// the console.log we expect to see from onDeleteClick is logged to console.
// the call does not seem to have registered though and the expect returns falsy
expect(deleteAccount.mock.calls.length).toBe(1);
})
});
问题可能是我将组件包装在提供程序中吗? 我有一个预感,但是我找不到任何具体的测试示例,这些示例在运行集成测试时使用提供程序包装其组件。
答案 0 :(得分:0)
解决方案是我需要从更改我的主要ParentComponent文件
class ParentComponent extends Component {
对此:
extend class ParentComponent extends Component {
,然后在我的测试文件中,导入组件,如下所示:
import { ParentComponent } from '../ParentComponent'; // non-default export should be wrapped in braces
然后更新测试,以便我像这样分配包装变量:
const wrapper = mount(<ParentComponent {...props} />);
然后允许测试通过
expect(deleteAccount.mock.calls.length).toBe(1);