【问题标题】:Enzyme simulate.('change', event) not working酶模拟。('改变',事件)不起作用
【发布时间】:2023-04-02 23:10:01
【问题描述】:

我正在尝试使用 karma/jasmine 为我的 react 应用程序执行单元测试。测试是检查状态是否发生了变化。我已经阅读了几篇参考资料,但似乎无法解决问题。此外, spyOn() 和 sinon.spy() 给出了错误的输出。

expect(received).toBe(expected)

Expected value to be (using ===):
  true
Received:
  false

测试-sn-p

        it('should call handleUserIdChange', () => {
            const value = '00000000';
            const mountedComponentHandle = mount(<LoginForm />);
            const onChangeUserID = sinon.spy(mountedComponentHandle.instance(), 'handleUserIdChange');
            mountedComponentHandle.update();
            (mountedComponentHandle.find('ValidatedInput').at(0)).simulate('change', value);
            expect(
                onChangeUserID.calledOnce
            ).toBe(true);
        });

为其编写测试的Login.js

class LoginForm extends Component {
    constructor(props) {
        super(props);
        this.state = {
            userId : '',
            password : '',
            loginType : ['Customer', 'Payer', 'Super-User'],
            userType : 'Customer',
            isLoggedIn : false,
            loginResponse : '',
            FieldsRegister : [],
        }
        this.handleClearForm = this.handleClearForm.bind(this);
        this.handleSubmitForm = this.handleSubmitForm.bind(this);
        this.handleUserIdChange = this.handleUserIdChange.bind(this);
        this.handlePasswordChange = this.handlePasswordChange.bind(this);
        this.handleUserTypeChangeSelect = this.handleUserTypeChangeSelect.bind(this);
        this.handleRegisterFormFields = this.handleRegisterFormFields.bind(this);
    }

    handleUserIdChange(value) {
        this.setState({ userId : value });
    }

    handlePasswordChange(value) {
        this.setState({ password : value });
    }
    ....
    render() {
        return (
            <form className="container form-horizontal"  onSubmit={this.handleSubmitForm}>
              <div className=" pb-10">
                <h2 className="text-center">Login</h2>
              </div>
              <div className='column text-center'>
                <span>{this.state.loginResponse}</span>
              </div>
                <ValidatedInput
                    name={'userId'}
                    type={'text'}
                    title={'User ID'}
                    value={this.state.userId}
                    placeholder={'Enter User ID'}
                    onChange={this.handleUserIdChange}
                    onComponentMounted={this.handleRegisterFormFields}
                    validations={/^[0-9]{4,10}$/}
                    validationError={'This is not valid user Id'}
                    isRequired={true}
                />
....

验证输入.js

class ValidatedInput extends Component {
    constructor(props) {
        super(props);

        this.state = {
            validations: this.props.validations,
            validationError: this.props.validationError
        };

        this.handleChangeValue = this.handleChangeValue.bind(this);
        this.isValid = this.isValid.bind(this);
        this.validateInput = this.validateInput.bind(this);
    }

    handleChangeValue(e) {
        this.props.onChange(e.target.value);
        var isValidField = this.isValid(e.target);
    }
....
render () {
        return (
            <div className="form-group">
                <div className="col-5 text-center">
                    <label htmlFor={this.props.name}>{this.props.title}</label>
                </div>
                <div className="col-5 text-center">
                    <input
                        className="form-input text-center"
                        type={this.props.type}
                        ref={this.props.name}
                        name={this.props.name}
                        value={this.props.value}
                        required={this.props.isRequired}
                        placeholder={this.props.placeholder}
                        onChange={this.handleChangeValue}
                    />
                    <span className='Error'></span>
                </div>
            </div>
        );
    }

有关如何检查state.userId 是否已更改的任何帮助以及有关如何通过测试的建议? 谢谢

【问题讨论】:

    标签: javascript reactjs unit-testing


    【解决方案1】:

    我找到了错误及其原因。 Refer this for explanation.

    更新了 test-sn-p:

    it('should call handleUserIdChange', () => {
        const value = '00000000';
        const mountedComponentHandle = mount(<LoginForm />);
        const onChangeUserId = sinon.spy(mountedComponentHandle.instance(), 'handleUserIdChange');
        mountedComponentHandle.update();
        mountedComponentHandle.find('input').at(0).simulate('change', value);
        expect(
            onChangeUserId.called
        ).toBe(true);
    });
    

    我们需要获取原生元素input 来模拟输入字段的变化。

    【讨论】:

      【解决方案2】:

      如果对某人有价值,我遇到了这个问题,我通过使用酶中的 "mount" 而不是 "shallow" 来解决它。更改后,模拟“更改”将正常工作

      【讨论】:

      • 这件事发生在我身上……很高兴能理解为什么……
      【解决方案3】:

      因此,对于您的测试,您似乎正在尝试查看是否已调用 handleUserIdChange。在这种情况下,您需要将handleUserIdChange 定义为sinonSpy() 并将其传递给LoginForm 组件的props。

      it('should call handleUserIdChange', () => {
        const value = '001251623';
        const handleUserIdChangeSpy = sinon.spy();
        const mountedComponentHandle = mount(<LoginForm handleUserIdChange={handleUserIdChangeSpy} />);
      
        mountedComponentHandle.find('ValidatedInput').at(0).simulate('change', value)
      
        expect(handleUserIdChangeSpy.calledOnce).toBe(true);
      });
      

      至于你在底部的问题,如果你想检查状态是否在调用后更新,你可以简单地模拟输入并在调用函数或与组件交互后使用.state() 检查状态以一种应该/不应该影响状态的方式。

      it('should update userId', () => {
         const mountedComponentHandle = mount(<LoginForm />);
         const value = '001251623';
      
         mountedComponentHandle.find('ValidatedInput').at(0).simulate('change', value)
         expect(mountedComponentHandle.state().userId).to.equal(value);
      });
      

      【讨论】:

      • 第一次测试仍然失败并出现同样的错误。而且,第二次测试也失败了。
      【解决方案4】:

      然后寻找组件显示名称.find('ValidatedInput')传入组件(构造函数)本身.find(ValidatedInput)

      【讨论】:

        猜你喜欢
        • 2018-11-05
        • 2017-01-30
        • 1970-01-01
        • 1970-01-01
        • 2018-03-30
        • 1970-01-01
        • 2018-09-11
        • 2012-06-17
        • 2015-06-03
        相关资源
        最近更新 更多