I have the following react-native test code.
import { shallow } from 'enzyme';
import React from 'react';
import {
BorderlessButton,
InputBox,
ProgressBar,
} from 'components';
import Name from '../name.component';
describe('Name component', () => {
let wrapper: any;
const mockOnPress = jest.fn();
const mockSaveStep = jest.fn();
const mockProps: any = {
errors: null,
values: [{ givenName: 'givenName', familyName: 'familyName' }],
};
beforeEach(() => {
wrapper = shallow(<Name signUpForm={mockProps} saveStep={mockSaveStep} />);
});
it('should render Name component', () => {
expect(wrapper).toMatchSnapshot();
});
it('should render 2 <InputBox />', () => {
expect(wrapper.find(InputBox)).toHaveLength(2);
});
it('should render a <ProgressBar />', () => {
expect(wrapper.find(ProgressBar)).toHaveLength(1);
});
it('should render a <BorderlessButton /> with the text NEXT', () => {
expect(wrapper.find(BorderlessButton)).toHaveLength(1);
expect(wrapper.find(BorderlessButton).props().text).toEqual('NEXT');
});
it('should press the NEXT button', () => {
wrapper.find(BorderlessButton).simulate('click');
expect(mockOnPress).toHaveBeenCalled();
});
});
But the last test doesn't work properly. How can I simulate a this button click? This gives me an error saying
expect(jest.fn()).toHaveBeenCalled(). Expected mock function to have been called, but it was not called.
This is the component.
class NameComponent extends Component {
componentDidMount() {
const { saveStep } = this.props;
saveStep(1, 'Name');
}
disableButton = () => {
const {
signUpForm: {
errors, values,
},
} = this.props;
if (errors && values && errors.givenName && errors.familyName) {
if (errors.givenName.length > 0 || values.givenName === '') return true;
if (errors.familyName.length > 0 || values.familyName === '') return true;
}
}
handleNext = () => {
navigationService.navigate('PreferredName');
}
resetForm = () => {
const { resetForm } = this.props;
resetForm(SIGN_UP_FORM);
navigationService.navigate('LoginMain');
}
render() {
const { name, required } = ValidationTypes;
const { step } = this.props;
return (
<SafeAreaView style={{ flex: 1 }}>
<KeyboardAvoidingView style={{ flex: 1 }}
behavior={Platform.OS === 'ios' ? 'padding' : null}
enabled>
<ScreenContainer
navType={ScreenContainer.Types.LEVEL_THREE}
levelThreeOnPress={this.resetForm}>
<View style={styles.container}>
<View style={{ flex: 1 }}>
<SinglifeText
type={SinglifeText.Types.H1}
label='Let’s start with your legal name'
style={styles.textLabel}
/>
<View style={styles.names}>
<InputBox
name='givenName'
form={SIGN_UP_FORM}
maxLength={22}
placeholder='Given name'
containerStyle={styles.givenNameContainer}
inputContainerStyle={styles.inputContainer}
errorStyles={styles.inputError}
keyboardType={KeyBoardTypes.default}
validations={[required, name]}
/>
<InputBox
name='familyName'
form={SIGN_UP_FORM}
maxLength={22}
placeholder='Family name'
inputContainerStyle={styles.inputContainer}
errorStyles={styles.inputError}
keyboardType={KeyBoardTypes.default}
validations={[required, name]}
/>
</View>
<SinglifeText
type={SinglifeText.Types.HINT}
label='Please use the same name you use with your bank'
style={styles.hint}
/>
</View>
</View>
</ScreenContainer>
<ProgressBar presentage={(step / MANUAL_SIGNUP_STEP_COUNT) * 100} />
<View style={styles.bottomButtonContainer}>
<BorderlessButton
text='NEXT'
disabled={this.disableButton()}
onPress={this.handleNext}
/>
</View>
</KeyboardAvoidingView>
</SafeAreaView>
);
}
}
How can I solve this??
You create the function mockOnPress()
, but mockOnPress()
is never injected into the component.
In the component you wrote, NameComponent
has a child BorderlessButton
component, in which the line, onPress={this.handleNext}
is hard-coded in. handleNext()
is defined elsewhere as:
handleNext = () => {
navigationService.navigate('PreferredName');
}
To test that the functionality of the button is working, I see two viable options. One is to use dependency injection . Instead of hard-coding the button to call navigationService.navigate('PreferredName')
, you could have it execute code that is passed in as a prop. See the following as an example:
it('Button should handle simulated click', function (done) {
wrappedButton = mount(<MyButton onClick={() => done()}>Click me!</BaseButton>)
wrappedButton.find('button').simulate('click')
}
Note that you could take the principle provided in the above example and expand it to your example by passing in the functionality you want to occur onClick as a prop to your NameComponent.
Another option you have, is to test whether clicking the button causes the side effects you want to occur. As written, pressing the button should call, navigationService.navigate('PreferredName')
. Is this the intended effect? If so, you can change your test to validate whether navigationService.navigate('PreferredName')
was called somehow.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.