2017-01-03 9 views
0

Я пытаюсь выполнить тестирование тестового компонента, который принимает пользовательский ввод. В частности, я пытаюсь проверить функцию onChange внутри реагирующего компонента. Однако я не могу установить значение ввода, я пробовал несколько разных способов, предложенных в Интернете, и ни один из них не работает. Ниже представлен компонент, который я пытаюсь проверить.Реагировать, как имитировать пользовательский ввод для модульного тестирования?

class Input extends Component { 
    constructor(props) { 
    super(props); 
    this.state = {value: ''}; 
    this.handleChange = this.handleChange.bind(this); 
    } 

    handleChange(event) { 
    /* Check if max length has been set. If max length has been 
    set make sure the user input is less than max Length, otherwise 
    return before updating the text string. */ 
    if(this.props.maxLength) { 
     if(event.target.value.length > this.props.maxLength) { 
     return; 
     } 
    } 
    this.setState({ value: event.target.value }); 
    } 

    render() { 
    const { disabled, label, maxLength, multiline, type, value, ...others} = this.props; 
    const theme = themeable(others.theme); 

    let inputClassName = classNames({ 
     "input": type !== 'checkbox', 
     "checkbox": type == 'checkbox', 
     disabled, 
     multiline, 
     value, 
     [`${this.props.className}`]: !!this.props.className 
    }); 

    return (
     <div {...theme(1, 'container')}> 
     {this.props.label ? <label htmlFor={this.props.htmlFor} {...theme(2, 'label')}>{label}</label> : null} 
      <input value={this.state.value} {...theme(3, ...inputClassName)} onChange={this.handleChange} type={type} /> 
     </div> 
    ); 
    } 
} 

Я нашел этот вопрос: https://github.com/airbnb/enzyme/issues/76 и попытался предложения, направленные вниз, я получаю либо не определено или пустая строка. Я попытался предложить левибузолику использовать симуляционные изменения фермента, которые можно увидеть ниже. Однако это только возвращает AssertionError: expected '' to equal 'abcdefghij'

it('Make sure inputted text is shorter than max length', function() { 
    const result = mount(<Input maxLength={10}></Input>); 
    result.find('input').simulate('change', {target: {value: 'abcdefghijk'}}); 
    expect(result.state().value).to.equal("abcdefghij"); 
}); 

Тогда я попробовал предложение takkyuuplayer, который является также ниже. Это также не с AssertionError: expected '' to equal 'abcdefghij'

it('Make sure inputted text is shorter than max length', function() { 
    const result = mount(<Input maxLength={10}></Input>); 
    result.find('input').node.value = 'abcdefghijk'; 
    expect(result.state().value).to.equal("abcdefghij"); 
    }); 

Я нашел эту статью: https://medium.com/javascript-inside/testing-in-react-getting-off-the-ground-5f569f3088a#.f4gcjbaak и пытались их путь, которым также не удалось.

it('Make sure inputted text is shorter than max length', function() { 
    const result = mount(<Input maxLength={10}></Input>); 
    let input = result.find('input'); 
    input.get(0).value = 'abcdefghijk'; 
    input.simulate('change'); 
    expect(result.state().value).to.equal("abcdefghij"); 
    }); 

Наконец я попытался с помощью реакции тест-утилиты, как предложено Simulating text entry with reactJs TestUtils ниже код, который я пытался, однако это не удалось с сообщением об ошибке: TypeError: Cannot read property '__reactInternalInstance$z78dboxwwtrznrmuut6wjc3di' of undefined

it('Make sure inputted text is shorter than max length', function() { 
    const result = mount(<Input maxLength={10}></Input>); 
    let input = result.find('input'); 
    TestUtils.Simulate.change(input, { target: { value: 'abcdefghijk' } }); 
    expect(result.state().value).to.equal("abcdefghij"); 
    }); 

Итак, как один синтезированным пользовательский ввод поэтому они могут протестировать функцию onChange?

ответ

2

У вас, похоже, есть ошибка в компоненте ввода. Когда event.target.value.length > this.props.maxLength вы никогда не устанавливаете фактическое состояние, оставляя state.value как ''. Кажется, вы ожидали, что оно будет установлено в значение, но усечено до maxLength. Вам нужно добавить, что сами:

handleChange(event) { 
    /* Check if max length has been set. If max length has been 
    set make sure the user input is less than max Length, otherwise 
    return before updating the text string. */ 
    if (this.props.maxLength) { 
    if (event.target.value.length > this.props.maxLength) { 
     // ** Truncate value to maxLength 
     this.setState({ value: event.target.value.substr(0, this.props.maxLength) }); 
     return; 
    } 
    } 
    this.setState({ value: event.target.value }); 
} 

... Затем, следующие тестовые работы и проходит:

it('Make sure inputted text is shorter than max length',() => { 
    const result = mount(<Input maxLength={10}></Input>); 
    result.find('input').simulate('change', { target: { value: '1234567890!!!' } }); 
    expect(result.state().value).to.equal("1234567890"); 
});