酶按钮模拟无法按预期工作
Posted
技术标签:
【中文标题】酶按钮模拟无法按预期工作【英文标题】:Enzyme button simulate doesn't work as expected 【发布时间】:2019-12-24 12:43:55 【问题描述】:我有以下 react-native 测试代码。
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();
);
);
但是最后一个测试不能正常工作。如何模拟此按钮单击?这给了我一个错误提示
期望(jest.fn()).toHaveBeenCalled()。 预期的模拟函数已被调用,但未被调用。
这是组件。
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>
);
我该如何解决这个问题??
【问题讨论】:
当您说“无法正常工作”时,您是什么意思?错误是什么? 我要测试的方法是,您还必须模拟单击按钮时将触发的函数并更改为 expect(function).toHaveBeencall(); 你能添加整个测试代码吗?这将帮助我们了解真正的问题出在哪里。 用完整的测试代码更新了帖子。 您调用的实际点击功能是什么?我猜 mockpress 只是一个模拟名称。您也可以发布组件代码吗?只是想看看你在 onclick 事件上调用了哪个函数。 【参考方案1】:您创建了函数mockOnPress()
,但从未将mockOnPress()
注入到组件中。
在您编写的组件中,NameComponent
有一个子BorderlessButton
组件,其中onPress=this.handleNext
行是硬编码的。handleNext()
在其他地方定义为:
handleNext = () =>
navigationService.navigate('PreferredName');
为了测试按钮的功能是否正常,我看到了两个可行的选项。一种是使用依赖注入。您可以让它执行作为道具传入的代码,而不是对按钮进行硬编码以调用navigationService.navigate('PreferredName')
。以以下为例:
it('Button should handle simulated click', function (done)
wrappedButton = mount(<MyButton onClick=() => done()>Click me!</BaseButton>)
wrappedButton.find('button').simulate('click')
请注意,您可以采用上面示例中提供的原则,并将您希望在 onClick 上发生的功能作为道具传递给您的 NameComponent,并将其扩展为您的示例。
您有另一个选择,是测试单击按钮是否会导致您想要发生的副作用。如前所述,按下按钮应调用navigationService.navigate('PreferredName')
。这是预期的效果吗?如果是这样,您可以更改测试以验证是否以某种方式调用了 navigationService.navigate('PreferredName')
。
【讨论】:
以上是关于酶按钮模拟无法按预期工作的主要内容,如果未能解决你的问题,请参考以下文章
在“if”语句中没有调用模拟函数 - 用玩笑和酶反应应用程序测试?
模拟 React useRef 或带有酶和玩笑的功能组件内的函数?