Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 模拟酶/反应单元测试中的形式变化不会改变字段值_Javascript_Reactjs_Enzyme - Fatal编程技术网

Javascript 模拟酶/反应单元测试中的形式变化不会改变字段值

Javascript 模拟酶/反应单元测试中的形式变化不会改变字段值,javascript,reactjs,enzyme,Javascript,Reactjs,Enzyme,我正在做一些基本的表单交互测试 const setup = (errors=false) => { let props = { budget: {}, errors: {}, onChange: () => {}, onSave: () => {} }; if (errors === true) { props.errors.budgetCategory= "error"; } return shallow(<Add

我正在做一些基本的表单交互测试

const setup = (errors=false) => {
  let props = {
    budget: {}, errors: {},
    onChange: () => {},
    onSave: () => {}
  };

  if (errors === true) {
    props.errors.budgetCategory= "error";
  }

  return shallow(<AddBudgetForm {...props} />);
};


describe("Fluctuating errors based on input values", () => {
  it("Renders an error when a number is present in the cost field", () => {
    let wrapper = setup();
    wrapper.find('[name="budgetCategory"]').simulate('change', { target: { value: '7' } });
    console.log(wrapper.find('[name="budgetCategory"]').props());
  });
});
理想情况下,我试图测试的是,模拟非数字的按键应该触发onChange处理程序向表单传播错误

我尝试在设置中添加新的onChange处理程序,但没有成功:

  let props = {
    budget: {}, errors: {},
    onChange: (e) => {props.budget.budgetCategory = e.target.value;},
    onSave: () => {}
  };
AddBudgetForm组件 从中,.simulate方法仅影响正在模拟的事件的事件属性。在这种情况下,您传递的合成事件参数将只提供给onChange函数。道具的实际价值不受影响

要确认,只需将自定义onChange处理程序更新为console.log,并记录提供给它的事件对象,例如

let props = {
    budget: {}, errors: {},
    onChange: (event) => { console.log(event); },
    onSave: () => {}
};
关于这一点的另一个问题是,正常的事件冒泡不会发生在这个模拟中-确保直接在要触发事件的节点上运行.simulate方法

重构的AddBudgetForm 注:这些只是小建议,不一定是唯一正确的方法

import React, { Component, PropTypes } from 'react';
import Alert from '../common/Alert';
import TextInput from '../common/TextInput';

const renderDays = () => Array(31).fill().map( 
    (_, i = 1) => <option key={i+1}>{i+1}</option> 
);

/**
 * Returns true if a key has a non-null value.
 * @param  {Object} errors - Errors object
 * @return {Boolean} Is there an error?
 */
const errorsInForm = errors => 
    Object.keys(errors).reduce( (hasError, item) => hasError || item != null, false);

const generateValidationError = error => <span style={{color: "red"}}>{error}</span>;

const AddBudgetForm = ({ budget, onChange, onSave, errors = {} }) => (
  <div name="AddBudgetForm">
    <form>
    { ! errorsInForm(errors)
      ? (
      <Alert
        name="add-budget-alert"
        alertType = "alert alert-info"
        fontAwesomeIcon = "fa fa-info"
        alertDescription = " Adding a budget is simple. Add a category such as groceries
        , allocate $200.00 per month and the day you'd like the budget to reset."
      />)
      : (
      <Alert
        name="add-budget-alert"
        alertType = "alert alert-danger"
        fontAwesomeIcon = "fa fa-warning"
        alertDescription = " There are problems with the form submission. Ensure all values in the form are valid."
      />
      )
    }

  <TextInput
      className="form-control"
      placeholder="Enter Name of Budget Category"
      onChange={onChange}
      value={budget.category}
      name="budgetCategory"
    />
  { errors.budgetCategory != "" && 
    generateValidationError(errors.budgetCategory)
  }

    <div className="form-group input-group">
      <span className="input-group-addon"><i className="fa fa-usd"></i></span>
      <input
        className="form-control"
        placeholder="Monthly Budget Cost"
        onChange={onChange}
        value={budget.cost}
        name="budgetCost"
      />
    </div>
  { errors.budgetCost != "" && 
    generateValidationError(errors.budgetCost) 
  }

    <select
      className="form-control"
      onChange={onChange}
      value={budget.date}
      name="budgetDate"
    >
      <option>Select Day of Month Budget Item is Due</option>
        { renderDays() }
    </select>
  { errors.budgetDate != "" && 
    generateValidationError(errors.budgetDate)
  }

    <br/>
    { ! errorsInForm(errors) 
      ? <button className="btn btn-primary" type="submit" onClick={() => onSave(budget)}>Add Budget</button>
      : <button className="btn btn-primary" type="submit" disabled>Fix Form Errors</button>
    }
    </form>
  </div>
);

AddBudgetForm.propTypes = {
  budget: PropTypes.object,
  onChange: PropTypes.func,
  onSave: PropTypes.func,
  errors: PropTypes.object
};

export default AddBudgetForm;

您正在使用一个以实际DOM元素右包装器为目标的选择器。查找“[name=budgetCategory]”。我假设在TextInput中有一个同名的输入。为什么不直接选择TextInput并调用其道具,例如:

wrapper.find('TextInput').prop('onChange')(<some value here>)

这应该可以正常工作-什么是wrapper.find“[name=budgetCategory]”。如果您使用console.log,那么长度是1,加上我在OP中编写的上述对象是记录wrapper.find返回值的结果。只是不确定为什么值保持未定义…@arsrasl我正在浅层渲染此组件,这是一个问题吗?@arsrasl当然,除非是因为我将自定义onChange处理程序作为一个道具传递,它是一个不做任何操作的函数…。您能提供一个修复示例吗?我看到我在onChange处理程序中记录了正确的事件,但在该处理程序中的budgetObject中设置一个新值实际上不会影响任何事情。我不确定我是否完全理解您的目标。你能澄清一下你在这次测试中需要什么吗。谢谢,我想插入一个数字,看看a模拟后输入中的值是一个数字,b组件用我的错误消息cool重新呈现。你能为AddBudgetForm组件添加代码吗
import React, { Component, PropTypes } from 'react';
import Alert from '../common/Alert';
import TextInput from '../common/TextInput';

const renderDays = () => Array(31).fill().map( 
    (_, i = 1) => <option key={i+1}>{i+1}</option> 
);

/**
 * Returns true if a key has a non-null value.
 * @param  {Object} errors - Errors object
 * @return {Boolean} Is there an error?
 */
const errorsInForm = errors => 
    Object.keys(errors).reduce( (hasError, item) => hasError || item != null, false);

const generateValidationError = error => <span style={{color: "red"}}>{error}</span>;

const AddBudgetForm = ({ budget, onChange, onSave, errors = {} }) => (
  <div name="AddBudgetForm">
    <form>
    { ! errorsInForm(errors)
      ? (
      <Alert
        name="add-budget-alert"
        alertType = "alert alert-info"
        fontAwesomeIcon = "fa fa-info"
        alertDescription = " Adding a budget is simple. Add a category such as groceries
        , allocate $200.00 per month and the day you'd like the budget to reset."
      />)
      : (
      <Alert
        name="add-budget-alert"
        alertType = "alert alert-danger"
        fontAwesomeIcon = "fa fa-warning"
        alertDescription = " There are problems with the form submission. Ensure all values in the form are valid."
      />
      )
    }

  <TextInput
      className="form-control"
      placeholder="Enter Name of Budget Category"
      onChange={onChange}
      value={budget.category}
      name="budgetCategory"
    />
  { errors.budgetCategory != "" && 
    generateValidationError(errors.budgetCategory)
  }

    <div className="form-group input-group">
      <span className="input-group-addon"><i className="fa fa-usd"></i></span>
      <input
        className="form-control"
        placeholder="Monthly Budget Cost"
        onChange={onChange}
        value={budget.cost}
        name="budgetCost"
      />
    </div>
  { errors.budgetCost != "" && 
    generateValidationError(errors.budgetCost) 
  }

    <select
      className="form-control"
      onChange={onChange}
      value={budget.date}
      name="budgetDate"
    >
      <option>Select Day of Month Budget Item is Due</option>
        { renderDays() }
    </select>
  { errors.budgetDate != "" && 
    generateValidationError(errors.budgetDate)
  }

    <br/>
    { ! errorsInForm(errors) 
      ? <button className="btn btn-primary" type="submit" onClick={() => onSave(budget)}>Add Budget</button>
      : <button className="btn btn-primary" type="submit" disabled>Fix Form Errors</button>
    }
    </form>
  </div>
);

AddBudgetForm.propTypes = {
  budget: PropTypes.object,
  onChange: PropTypes.func,
  onSave: PropTypes.func,
  errors: PropTypes.object
};

export default AddBudgetForm;
wrapper.find('TextInput').prop('onChange')(<some value here>)