New to testing and This is a connected component using redux. I am testing if the maskPromoCode function is called. With the current test code, the error says: Cannot spyOn on a primitive value; undefined given
Do not understand why. Thanks.
The component:
class Textbox extends React.Component {
constructor(props) {
super(props);
}
onChange(e) {
e.preventDefault();
this.setState({
value: this.maskPromoCode(e.target.value)
})
}
maskPromoCode(value) {...}
render() {
return (
<>
<input
...
onChange={e => this.onChange(e)}
/>
</>
);
}
}
const mapDispatchToProps = { setError, setPwError };
export default connect(null, mapDispatchToProps)(Textbox);
The test file
it('invokes the maskPromoCode function with event value', () => {
const funcMock = jest.spyOn(Textbox.prototype, 'maskPromoCode');
const wrapper = mount(
<Provider store={store}>
<Textbox {...baseProps} name="redeem-promo" />
</Provider>
);
const inputField = wrapper.find('input');
const event = {
target: {
value: 'event value',
},
};
inputField.simulate('change', event);
expect(funcMock).toHaveBeenCalledWith(event.target.value);
});
CodePudding user response:
The
Textboxcomponent is wrapped by theconnectfunction, it becomes a HOC that has noprototype, I guess you import the HOC in your test file. TheTextBoxcomponent imported in the test file is a HOC. SoTextBox.prototypeisundefined, that's whyjest.spyOnthrows error.If you insist to use
jest.spyOn()for themaskPromoCodemethod, you can usejest.spyOn(Textbox.WrappedComponent.prototype, 'maskPromoCode'). There is a WrappedComponent static property on HOC, so you can get the original component class.Recommend: You are testing the implementation details if using
jest.spyOn(...), you should test the component behavior.
E.g.
Textbox.jsx:
import React from 'react';
import { connect } from 'react-redux';
class Textbox extends React.Component {
constructor(props) {
super(props);
this.state = { value: '131' };
}
onChange(e) {
e.preventDefault();
this.setState({ value: this.maskPromoCode(e.target.value) });
}
maskPromoCode(value) {
return '***';
}
render() {
return (
<>
<input value={this.state.value} onChange={(e) => this.onChange(e)} />
</>
);
}
}
export default connect(null, null)(Textbox);
Textbox.test.jsx:
import Textbox from './Textbox';
import React from 'react';
import configureStore from 'redux-mock-store';
import { Provider } from 'react-redux';
describe('70795348', () => {
it('invokes the maskPromoCode function with event value', () => {
console.log(Textbox.WrappedComponent.prototype.maskPromoCode);
const mockStore = configureStore();
const store = mockStore();
const wrapper = mount(
<Provider store={store}>
<Textbox name="redeem-promo" />
</Provider>
);
expect(wrapper.find('input').instance().value).toBe('131');
const event = { target: { value: 'event value' } };
wrapper.find('input').simulate('change', event);
expect(wrapper.find('input').instance().value).toBe('***');
});
});
Test result:
PASS stackoverflow/70795348/Textbox.test.jsx
70795348
✓ invokes the maskPromoCode function with event value (40 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 2.729 s, estimated 9 s
