我在React应用程序中使用formik + material-ui构建了一个表单。 并想用Jest,酶和sinon测试输入的onChange事件。
我使用setTimeout()是因为Formik的处理程序是异步的,酶的更改事件是同步的。
测试“如果值在输入更改时显示”将失败。
const input = wrapper.find('#username');
input.simulate('change', { target: { name: 'username', value: 'y' }
setTimeout(() => {
expect(mockChange.calledOnce).toBe(true); // test is passed.
expect(input.props().value).toEqual('y'); // Expected value to equal: "y" , Received: ""
done();
}, 1000);
...
render() {
const values = { username: '', password: '' };
return (
<React.Fragment>
<Formik
initialValues={values}
render={props => <Form {...props} />}
onSubmit={this.handleUserLogin}
validationSchema={loginValidation}
/>
</React.Fragment>
);
}
...
import React from 'react';
import TextField from '@material-ui/core/TextField';
...
const styles = theme => ({ });
const Form = props => {
const {
values: { username, password },
errors,
touched,
handleChange,
handleSubmit,
isSubmitting,
handleBlur,
classes,
} = props;
return (
<div className="login-container" data-test="loginformComponent">
<form onSubmit={handleSubmit} className="flex flex-column-m items-center">
<TextField
id="username"
value={username || ''}
onChange={handleChange}
...
/>
<TextField
id="password"
value={password || ''}
onChange={handleChange}
...
/>
...
</form>
</div>
);
};
export const Unwrapped = Form;
export default withStyles(styles)(Form);
import React, { shallow, sinon } from '../../__tests__/setupTests';
import { Unwrapped as UnwrappedLoginForm } from './loginForm';
const mockBlur = jest.fn();
const mockChange = sinon.spy();
const mockSubmit = sinon.spy();
const setUp = (props = {}) => {
const component = shallow(<UnwrappedLoginForm {...props} />);
return component;
};
describe('Login Form Component', () => {
let wrapper;
beforeEach(() => {
const props = {
values: { username: '', password: '' },
errors: { username: false, password: false },
touched: { username: false, password: false },
handleChange: mockChange,
handleSubmit: mockSubmit,
isSubmitting: false,
handleBlur: mockBlur,
classes: {
textField: '',
},
};
wrapper = setUp(props);
});
describe('When the input value is inserted', () => {
it('renders new username value', done => {
const input = wrapper.find('#username');
input.simulate('change', { target: { name: 'username', value: 'y' } });
setTimeout(() => {
wrapper.update();
expect(mockChange.calledOnce).toEqual(true);
done();
}, 1000);
});
});
});
答案 0 :(得分:0)
请尝试以下操作:
const waitForNextTick = process.nextTick
waitForNextTick(() => {
expect(mockChange.calledOnce).toBe(true); // test is passed.
expect(input.props().value).toEqual('y'); // Expected value to equal: "y" , Received: ""
done();
});
答案 1 :(得分:0)
根据您提供的代码,我认为输入的值不会被更新。
您正在change
组件上触发TextField
事件。这触发的是输入的onChange
回调,它依次执行handleChange
组件的UnwrappedLoginForm
属性。但这并不会改变输入值本身。