使用 Enzyme、Sinon 和 ChaionChange 测试 onChange 没有被调用?
Testing onChange using Enzyme, Sinon and Chai- onChange is not called?
我正在尝试为 rc-select 编写一些测试。
我要做的测试是检查是否调用了 onChange 函数。
我目前拥有的:
测试组件,使用样式化版本的 rc-select:
ReactSelectTestComponent.jsx
import React from 'react';
import Select from '../../packages/lab/src/select/Select.jsx';
const ReactSelectTestComponent = (props) => {
const { options } = props;
const onChange = (event) => {
if (props.onChange) {
props.onChange(event)
}
}
return (
<div>
<Select
name='test'
value='one'
options={options}
onChange={onChange}
/>
</div >
)
}
export default ReactSelectTestComponent;
Select.test.js:
import SelectTestComponent from './SelectTestComponent'
import sinon from 'sinon';
import { expect as chaiExpect } from 'chai'; // Using Expect style
describe('Testing Select component', () => {
it('should call onChange', () => {
const onChange = sinon.spy();
const options =
[
{ label: 'one', value: 'one' },
{ label: 'two', value: 'two' }
];
const wrapper = mount(<SelectTestComponent onChange={onChange} options={options} />);
console.log("wrapper.debug()", wrapper.debug())
const selectWrapper = wrapper.find('Select').first();
selectWrapper.simulate('change', { target: { value: "testtest" } })
selectWrapper.update()
chaiExpect(onChange.called).to.be.true;
});
})
但是,我遇到了这个错误。
Expected value true
Received:
false
Message:
expected false to be true
38 | selectWrapper.update()
39 |
> 40 | chaiExpect(onChange.called).to.be.true;
| ^
41 | });
42 |
43 | /*
at Object.<anonymous> (tests/src/Select.test.js:40:9)
是否有另一个 select 或者我应该在 find() 调用中使用?我觉得我已经尝试了所有的选择。
console.log(wrapper.debug()):
ReactSelectTestComponent options={{...}}>
<div>
<ForwardRef name="test" value="one" options={{...}} onChange={[Function: onChange]} menuItemSelectedIcon={{...}}>
<Memo(l) />
<Styled(Select) className={[undefined]} value="one" inputIcon={{...}} menuItemSelectedIcon={{...}} name="test" onChange={[Function: onChange]}>
<Select className="sc-kBqltT caYcRD" value="one" inputIcon={{...}} menuItemSelectedIcon={{...}} name="test" onChange={[Function: onChange]}>
<ForwardRef(Select) className="sc-kBqltT caYcRD" value="one" inputIcon={{...}} menuItemSelectedIcon={{...}} name="test" onChange={[Function: onChange]}>
<div className="rc-select sc-kBqltT caYcRD rc-select-single rc-select-show-arrow" name="test" onMouseDown={[Function: onInternalMouseDown]} onKeyDown={[Function: onInternalKeyDown]} onKeyUp={[Function: onInternalKeyUp]} onFocus={[Function: onContainerFocus]} onBlur={[Function: onContainerBlur]}>
<SelectTrigger disabled={[undefined]} prefixCls="rc-select" visible={[undefined]} popupElement={{...}} containerWidth={{...}} animation={[undefined]} transitionName={[undefined]} dropdownStyle={[undefined]} dropdownClassName={[undefined]} direction={[undefined]} dropdownMatchSelectWidth={[undefined]} dropdownRender={[undefined]} dropdownAlign={[undefined]} getPopupContainer={[undefined]} empty={false} getTriggerDOMNode={[Function: getTriggerDOMNode]}>
<Trigger showAction={{...}} hideAction={{...}} popupPlacement="bottomLeft" builtinPlacements={{...}} prefixCls="rc-select-dropdown" popupTransitionName={[undefined]} popup={{...}} popupAlign={{...}} popupVisible={[undefined]} getPopupContainer={[undefined]} popupClassName="" popupStyle={{...}} getTriggerDOMNode={[Function: getTriggerDOMNode]} getPopupClassNameFromAlign={[Function: returnEmptyString]} getDocument={[Function: returnDocument]} onPopupVisibleChange={[Function: noop]} afterPopupVisibleChange={[Function: noop]} onPopupAlign={[Function: noop]} mouseEnterDelay={0} mouseLeaveDelay={0.1} focusDelay={0} blurDelay={0.15} destroyPopupOnHide={false} defaultPopupVisible={false} mask={false} maskClosable={true} action={{...}} autoDestroy={false}>
<Selector className="sc-kBqltT caYcRD" value="one" inputIcon={{...}} menuItemSelectedIcon={{...}} name="test" onChange={[Function: onChange]} domRef={{...}} prefixCls="rc-select" inputElement={{...}} id="rc_select_TEST_OR_SSR" showSearch={false} mode={[undefined]} accessibilityIndex={0} multiple={false} tagRender={[undefined]} values={{...}} open={[undefined]} onToggleOpen={[Function: onToggleOpen]} searchValue="" activeValue={{...}} onSearch={[Function: triggerSearch]} onSearchSubmit={[Function: onSearchSubmit]} onSelect={[Function: onInternalSelectionSelect]} tokenWithEnter={false} onContextMenu={[undefined]} onClick={[undefined]} onMouseDown={[undefined]} onTouchStart={[undefined]} onMouseEnter={[undefined]} onMouseLeave={[undefined]} onFocus={[undefined]} onBlur={[undefined]}>
<div className="rc-select-selector" onClick={[Function: onClick]} onMouseDown={[Function: onMouseDown]}>
<SingleSelector className="sc-kBqltT caYcRD" value="one" inputIcon={{...}} menuItemSelectedIcon={{...}} name="test" onChange={[Function: onChange]} domRef={{...}} prefixCls="rc-select" inputElement={{...}} id="rc_select_TEST_OR_SSR" showSearch={false} mode={[undefined]} accessibilityIndex={0} multiple={false} tagRender={[undefined]} values={{...}} open={[undefined]} onToggleOpen={[Function: onToggleOpen]} searchValue="" activeValue={{...}} onSearch={[Function: triggerSearch]} onSearchSubmit={[Function: onSearchSubmit]} onSelect={[Function: onInternalSelectionSelect]} tokenWithEnter={false} onContextMenu={[undefined]} onClick={[undefined]} onMouseDown={[undefined]} onTouchStart={[undefined]} onMouseEnter={[undefined]} onMouseLeave={[undefined]} onFocus={[undefined]} onBlur={[undefined]} inputRef={{...}} onInputKeyDown={[Function: onInternalInputKeyDown]} onInputMouseDown={[Function: onInternalInputMouseDown]} onInputChange={[Function: onInputChange]} onInputPaste={[Function: onInputPaste]} onInputCompositionStart={[Function: onInputCompositionStart]} onInputCompositionEnd={[Function: onInputCompositionEnd]}>
<span className="rc-select-selection-search">
<Input prefixCls="rc-select" id="rc_select_TEST_OR_SSR" open={[undefined]} inputElement={{...}} disabled={[undefined]} autoFocus={[undefined]} autoComplete={[undefined]} editable={false} accessibilityIndex={0} value="" onKeyDown={[Function: onInternalInputKeyDown]} onMouseDown={[Function: onInternalInputMouseDown]} onChange={[Function: onChange]} onPaste={[Function: onInputPaste]} onCompositionStart={[Function: onInputCompositionStart]} onCompositionEnd={[Function: onInputCompositionEnd]} tabIndex={[undefined]} attrs={{...}}>
<input id="rc_select_TEST_OR_SSR" disabled={[undefined]} tabIndex={[undefined]} autoComplete="off" type="search" autoFocus={[undefined]} className="rc-select-selection-search-input" style={{...}} role="combobox" aria-expanded={[undefined]} aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" aria-activedescendant="rc_select_TEST_OR_SSR_list_0" value="" readOnly={true} unselectable="on" onKeyDown={[Function: onKeyDown]} onMouseDown={[Function: onMouseDown]} onChange={[Function: onChange]} onCompositionStart={[Function: onCompositionStart]} onCompositionEnd={[Function: onCompositionEnd]} onPaste={[Function: onInputPaste]} />
</Input>
</span>
<span className="rc-select-selection-item" title="one">
one
</span>
</SingleSelector>
</div>
</Selector>
</Trigger>
</SelectTrigger>
<TransBtn className="rc-select-arrow" customizeIcon={{...}} customizeIconProps={{...}}>
<span className="rc-select-arrow" onMouseDown={[Function: onMouseDown]} style={{...}} unselectable="on" onClick={[undefined]} aria-hidden={true}>
<styled.div>
<div className="sc-ezjryM fUxvmA">
<ForwardRef type="chevron_down" color="#dcdcdc" size={24} rotation={0}>
<styled.span className={[undefined]} color="#dcdcdc" width={24} height={24} rotation={0}>
<span className="sc-cGKHXZ jHIRgh" color="#dcdcdc" width={24} height={24}>
<svg fill="currentcolor" border="currentcolor" viewBox="0 0 24 24" width="24" height="24" xmlns="http://www.w3.org/2000/svg">
<path fillRule="evenodd" clipRule="evenodd" d="M7.41 8.295l4.59 4.58 4.59-4.58L18 9.705l-6 6-6-6 1.41-1.41z" />
</svg>
</span>
</styled.span>
</ForwardRef>
</div>
</styled.div>
</span>
</TransBtn>
</div>
</ForwardRef(Select)>
</Select>
</Styled(Select)>
</ForwardRef>
</div>
</ReactSelectTestComponent>
工作测试:(需要通过包装器的 props 调用 onChange。
it("Checking if onChange prop function is called", () => {
const onChange = sinon.spy();
const wrapper = mount(
<SelectTestComponent onChange={onChange} options={options} />
);
const func = wrapper.find("Select").props().onChange;
console.log(wrapper.find("Select").props());
func({ target: { value: "test" } });
chaiExpect(onChange.called).to.be.true;
});
我正在尝试为 rc-select 编写一些测试。
我要做的测试是检查是否调用了 onChange 函数。 我目前拥有的:
测试组件,使用样式化版本的 rc-select:
ReactSelectTestComponent.jsx
import React from 'react';
import Select from '../../packages/lab/src/select/Select.jsx';
const ReactSelectTestComponent = (props) => {
const { options } = props;
const onChange = (event) => {
if (props.onChange) {
props.onChange(event)
}
}
return (
<div>
<Select
name='test'
value='one'
options={options}
onChange={onChange}
/>
</div >
)
}
export default ReactSelectTestComponent;
Select.test.js:
import SelectTestComponent from './SelectTestComponent'
import sinon from 'sinon';
import { expect as chaiExpect } from 'chai'; // Using Expect style
describe('Testing Select component', () => {
it('should call onChange', () => {
const onChange = sinon.spy();
const options =
[
{ label: 'one', value: 'one' },
{ label: 'two', value: 'two' }
];
const wrapper = mount(<SelectTestComponent onChange={onChange} options={options} />);
console.log("wrapper.debug()", wrapper.debug())
const selectWrapper = wrapper.find('Select').first();
selectWrapper.simulate('change', { target: { value: "testtest" } })
selectWrapper.update()
chaiExpect(onChange.called).to.be.true;
});
})
但是,我遇到了这个错误。
Expected value true
Received:
false
Message:
expected false to be true
38 | selectWrapper.update()
39 |
> 40 | chaiExpect(onChange.called).to.be.true;
| ^
41 | });
42 |
43 | /*
at Object.<anonymous> (tests/src/Select.test.js:40:9)
是否有另一个 select 或者我应该在 find() 调用中使用?我觉得我已经尝试了所有的选择。
console.log(wrapper.debug()):
ReactSelectTestComponent options={{...}}>
<div>
<ForwardRef name="test" value="one" options={{...}} onChange={[Function: onChange]} menuItemSelectedIcon={{...}}>
<Memo(l) />
<Styled(Select) className={[undefined]} value="one" inputIcon={{...}} menuItemSelectedIcon={{...}} name="test" onChange={[Function: onChange]}>
<Select className="sc-kBqltT caYcRD" value="one" inputIcon={{...}} menuItemSelectedIcon={{...}} name="test" onChange={[Function: onChange]}>
<ForwardRef(Select) className="sc-kBqltT caYcRD" value="one" inputIcon={{...}} menuItemSelectedIcon={{...}} name="test" onChange={[Function: onChange]}>
<div className="rc-select sc-kBqltT caYcRD rc-select-single rc-select-show-arrow" name="test" onMouseDown={[Function: onInternalMouseDown]} onKeyDown={[Function: onInternalKeyDown]} onKeyUp={[Function: onInternalKeyUp]} onFocus={[Function: onContainerFocus]} onBlur={[Function: onContainerBlur]}>
<SelectTrigger disabled={[undefined]} prefixCls="rc-select" visible={[undefined]} popupElement={{...}} containerWidth={{...}} animation={[undefined]} transitionName={[undefined]} dropdownStyle={[undefined]} dropdownClassName={[undefined]} direction={[undefined]} dropdownMatchSelectWidth={[undefined]} dropdownRender={[undefined]} dropdownAlign={[undefined]} getPopupContainer={[undefined]} empty={false} getTriggerDOMNode={[Function: getTriggerDOMNode]}>
<Trigger showAction={{...}} hideAction={{...}} popupPlacement="bottomLeft" builtinPlacements={{...}} prefixCls="rc-select-dropdown" popupTransitionName={[undefined]} popup={{...}} popupAlign={{...}} popupVisible={[undefined]} getPopupContainer={[undefined]} popupClassName="" popupStyle={{...}} getTriggerDOMNode={[Function: getTriggerDOMNode]} getPopupClassNameFromAlign={[Function: returnEmptyString]} getDocument={[Function: returnDocument]} onPopupVisibleChange={[Function: noop]} afterPopupVisibleChange={[Function: noop]} onPopupAlign={[Function: noop]} mouseEnterDelay={0} mouseLeaveDelay={0.1} focusDelay={0} blurDelay={0.15} destroyPopupOnHide={false} defaultPopupVisible={false} mask={false} maskClosable={true} action={{...}} autoDestroy={false}>
<Selector className="sc-kBqltT caYcRD" value="one" inputIcon={{...}} menuItemSelectedIcon={{...}} name="test" onChange={[Function: onChange]} domRef={{...}} prefixCls="rc-select" inputElement={{...}} id="rc_select_TEST_OR_SSR" showSearch={false} mode={[undefined]} accessibilityIndex={0} multiple={false} tagRender={[undefined]} values={{...}} open={[undefined]} onToggleOpen={[Function: onToggleOpen]} searchValue="" activeValue={{...}} onSearch={[Function: triggerSearch]} onSearchSubmit={[Function: onSearchSubmit]} onSelect={[Function: onInternalSelectionSelect]} tokenWithEnter={false} onContextMenu={[undefined]} onClick={[undefined]} onMouseDown={[undefined]} onTouchStart={[undefined]} onMouseEnter={[undefined]} onMouseLeave={[undefined]} onFocus={[undefined]} onBlur={[undefined]}>
<div className="rc-select-selector" onClick={[Function: onClick]} onMouseDown={[Function: onMouseDown]}>
<SingleSelector className="sc-kBqltT caYcRD" value="one" inputIcon={{...}} menuItemSelectedIcon={{...}} name="test" onChange={[Function: onChange]} domRef={{...}} prefixCls="rc-select" inputElement={{...}} id="rc_select_TEST_OR_SSR" showSearch={false} mode={[undefined]} accessibilityIndex={0} multiple={false} tagRender={[undefined]} values={{...}} open={[undefined]} onToggleOpen={[Function: onToggleOpen]} searchValue="" activeValue={{...}} onSearch={[Function: triggerSearch]} onSearchSubmit={[Function: onSearchSubmit]} onSelect={[Function: onInternalSelectionSelect]} tokenWithEnter={false} onContextMenu={[undefined]} onClick={[undefined]} onMouseDown={[undefined]} onTouchStart={[undefined]} onMouseEnter={[undefined]} onMouseLeave={[undefined]} onFocus={[undefined]} onBlur={[undefined]} inputRef={{...}} onInputKeyDown={[Function: onInternalInputKeyDown]} onInputMouseDown={[Function: onInternalInputMouseDown]} onInputChange={[Function: onInputChange]} onInputPaste={[Function: onInputPaste]} onInputCompositionStart={[Function: onInputCompositionStart]} onInputCompositionEnd={[Function: onInputCompositionEnd]}>
<span className="rc-select-selection-search">
<Input prefixCls="rc-select" id="rc_select_TEST_OR_SSR" open={[undefined]} inputElement={{...}} disabled={[undefined]} autoFocus={[undefined]} autoComplete={[undefined]} editable={false} accessibilityIndex={0} value="" onKeyDown={[Function: onInternalInputKeyDown]} onMouseDown={[Function: onInternalInputMouseDown]} onChange={[Function: onChange]} onPaste={[Function: onInputPaste]} onCompositionStart={[Function: onInputCompositionStart]} onCompositionEnd={[Function: onInputCompositionEnd]} tabIndex={[undefined]} attrs={{...}}>
<input id="rc_select_TEST_OR_SSR" disabled={[undefined]} tabIndex={[undefined]} autoComplete="off" type="search" autoFocus={[undefined]} className="rc-select-selection-search-input" style={{...}} role="combobox" aria-expanded={[undefined]} aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" aria-activedescendant="rc_select_TEST_OR_SSR_list_0" value="" readOnly={true} unselectable="on" onKeyDown={[Function: onKeyDown]} onMouseDown={[Function: onMouseDown]} onChange={[Function: onChange]} onCompositionStart={[Function: onCompositionStart]} onCompositionEnd={[Function: onCompositionEnd]} onPaste={[Function: onInputPaste]} />
</Input>
</span>
<span className="rc-select-selection-item" title="one">
one
</span>
</SingleSelector>
</div>
</Selector>
</Trigger>
</SelectTrigger>
<TransBtn className="rc-select-arrow" customizeIcon={{...}} customizeIconProps={{...}}>
<span className="rc-select-arrow" onMouseDown={[Function: onMouseDown]} style={{...}} unselectable="on" onClick={[undefined]} aria-hidden={true}>
<styled.div>
<div className="sc-ezjryM fUxvmA">
<ForwardRef type="chevron_down" color="#dcdcdc" size={24} rotation={0}>
<styled.span className={[undefined]} color="#dcdcdc" width={24} height={24} rotation={0}>
<span className="sc-cGKHXZ jHIRgh" color="#dcdcdc" width={24} height={24}>
<svg fill="currentcolor" border="currentcolor" viewBox="0 0 24 24" width="24" height="24" xmlns="http://www.w3.org/2000/svg">
<path fillRule="evenodd" clipRule="evenodd" d="M7.41 8.295l4.59 4.58 4.59-4.58L18 9.705l-6 6-6-6 1.41-1.41z" />
</svg>
</span>
</styled.span>
</ForwardRef>
</div>
</styled.div>
</span>
</TransBtn>
</div>
</ForwardRef(Select)>
</Select>
</Styled(Select)>
</ForwardRef>
</div>
</ReactSelectTestComponent>
工作测试:(需要通过包装器的 props 调用 onChange。
it("Checking if onChange prop function is called", () => {
const onChange = sinon.spy();
const wrapper = mount(
<SelectTestComponent onChange={onChange} options={options} />
);
const func = wrapper.find("Select").props().onChange;
console.log(wrapper.find("Select").props());
func({ target: { value: "test" } });
chaiExpect(onChange.called).to.be.true;
});