[英]Jest Enzyme Cannot spy the property because it is not a function; undefined given instead when spyOn testing a function in component
I am testing on the execution of functions inside a React component that's connected to redux store.我正在测试连接到 redux 存储的 React 组件内的函数执行。 I was only able to spy on some of the functions, the rest all returned: Cannot spy the setEmail(or other function names) property because it is not a function;我只能监视某些功能,rest 全部返回:无法监视 setEmail(或其他 function 名称) 属性,因为它不是 ZC1C425268E68384D1AB5074C1 undefined given instead给定的未定义
below in code I added arrows pointing out which ones are spy-able, when I console.log(BaseForm.WrappedComponent.prototype.functionName) the ones that are not spy-able returned undefined.在下面的代码中,我添加了箭头,指出哪些是可监视的,当我 console.log(BaseForm.WrappedComponent.prototype.functionName) 那些不可监视的返回未定义时。 the one that can be spied on returned [Function:...] I really do not understand why?可以窥探的返回[功能:...]我真的不明白为什么?
class BaseForm extends React.Component {
constructor(props) {
super(props);
this.state = {
ages: [],
};
}
componentDidMount() {
this.createAges(); <----- can spy on this one as it is a function
}
setEmail = (elemName, value) => { <------ Cannot spy the setEmail property because it is not a function; undefined
this.setState({ email: value });
this.props.saveEmail(value);
};
handleEmailSignup = (e) => { <-------- Cannot spy the setEmail property because it is not a function; undefined
this.setState({ offersSignup: e.target.checked });
};
onChangeAge = (e) => { <------ Cannot spy the setEmail property because it is not a function; undefined
this.setState({
selectedAge: e.target.value,
selectedAgeIndex: e.target.index - 1,
errorAge: '',
});
};
createAges() { <------ can spyOn as it is a function
let ages = [
{ value: '', text: !__isEmpty(sessionStorage.getItem('gf')) ? 'Kid age' : 'Your age' },
{ value: '14 and younger', text: '14 and younger' },
{ value: '15', text: '15' },
{ value: '16', text: '16' },
{ value: '17', text: '17' },
];
this.setState({ ages: ages });
}
render() {
return (
<div>
<div data-type="email" className="textbox-wrapper">
<Textbox
type="email"
placeholder="Email Address"
name="register-email"
onChange={this.setEmail}
onBlur={this.checkUserByEmail}
defaultValue={this.state.email}
isError={!__isEmpty(this.props.emailErrorClass)}
/>
</div>
<Dropdown options={this.state.ages} onChange={this.onChangeAge} selectedValue={this.state.selectedAge} />
<div>
<input name="offersSignup" type="checkbox" onChange={this.handleEmailSignup} checked={this.state.offersSignup} />
</div>
</div>
);
}
}
const mapDispatchToProps = { saveEmail };
export default connect(null, mapDispatchToProps)(BaseForm);
it.only('set email in local state if onChange of Textbox is fired', () => {
//console.log(BasePartnerRegistrationForm.WrappedComponent.prototype.setEmail);
// above is undefined
const setEmailSpy = jest.spyOn(BaseForm.WrappedComponent.prototype, 'setEmail');
const wrapper = mount(
<Provider store={store}>
<BaseForm {...baseProps} />
</Provider>
);
const event = { target: { value: 'event value' } };
wrapper.find('Textbox').at(0).simulate('change', event);
wrapper.update();
expect(setEmailSpy).toHaveBeenCalled();
// below shows unchanged email value in state
// expect(wrapper.find('Textbox').at(0).props().defaultValue).toBe(event.target.value);
});
Rather than spying on the method call, just check the DOM.与其监视方法调用,不如检查 DOM。 First, I would suggest you look at React Testing Library for finding fields, setting values, querying the DOM for changes.首先,我建议您查看React 测试库以查找字段、设置值、查询 DOM 以进行更改。 This, with Jest, is the new standard in React testing (even included with React-Create-App).这与 Jest 一起是 React 测试中的新标准(甚至包含在 React-Create-App 中)。 It's a paradigm shift, in that use test user interaction and result (as a user would), which is testing the underlying logic.这是一种范式转变,使用测试用户交互和结果(就像用户一样),它正在测试底层逻辑。
The next thing to consider is timing.接下来要考虑的是时机。 When you set state it isn't immediate.当您设置 state 时,它不是立即的。 It takes a few milliseconds for state changes to render. state 更改需要几毫秒才能呈现。 RTL provides a waitFor
method that simplifies this further. RTL 提供了一个waitFor
方法,进一步简化了这个过程。
waitFor(() => /*some assertion*/);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.