[英]Enzyme button simulate doesn't work as expected
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().
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. 您创建了函数
mockOnPress()
,但是mockOnPress()
从未注入到组件中。
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: 在您编写的组件中,
NameComponent
有一个子级BorderlessButton
组件,其中onPress={this.handleNext}
这行硬编码在其中handleNext()
在其他地方定义为:
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. 您可以使按钮执行作为道具传入的代码,而不是对按钮进行硬编码以调用
navigationService.navigate('PreferredName')
。 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. 请注意,您可以采用上面示例中提供的原理,并通过将要发生onClick的功能作为对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')
. 按照书面规定,按下按钮应调用
navigationService.navigate('PreferredName')
。 Is this the intended effect? 这是预期的效果吗? If so, you can change your test to validate whether
navigationService.navigate('PreferredName')
was called somehow. 如果是这样,则可以更改测试以验证是否以某种方式调用了
navigationService.navigate('PreferredName')
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.