【问题标题】:Mocking user input for TDD for React using Mocha, Chai and JSDom?使用 Mocha、Chai 和 JSDom 模拟 TDD for React 的用户输入?
【发布时间】:2016-12-01 21:16:34
【问题描述】:

我有一个要测试用户输入的搜索栏。我正在使用 React 渲染视图并使用 Chai、Mocha 和 JSDom 编写测试。

这是我目前编写的简单测试

 describe('Search', () => {
    it('renders a search bar', () => {
        const component = renderIntoDocument(
            <Search />
        );
        const search_bar = scryRenderedDOMComponentsWithClass(component, 'input-group');

        expect(search_bar.length).to.equal(1);
    });

    it('invokes a callback when the Add button is clicked', () => {
        let search_term;
        const clickHandler = (term) => search_term = term;

        const component = renderIntoDocument(
            <Search onClick={clickHandler}/>
        )

        const add_button = scryRenderedDOMComponentsWithTag(component, 'button');
        Simulate.click(add_button[0]);

        expect(search_term).to.equal('');
    });

    it('accepts user input from the search button and performs a regex check for invalid input', () => {
        let search_term;
        const clickHandler = (term) => search_term = term;

        const component = renderIntoDocument(
            <Search onClick={clickHandler} />
        );

        const add_button = scryRenderedDOMComponentsWithTag(component, 'button');
        const search_bar = scryRenderedDOMComponentsWithClass(component, 'input-group');

        Simulate.change(search_bar[0], {target: {value: 'FB'}});
        expect(search_bar[0].state.value).to.equal('FB');
    })
})

1) 我想测试用户在点击添加按钮之前是否输入了字符。

2) 我想测试用户没有在搜索词中输入任何数字或特殊字符,字符串需要只有字母。

如何模拟这些测试?

【问题讨论】:

    标签: unit-testing reactjs


    【解决方案1】:

    好的,经过一些调试,我得到了答案。但是,这似乎有点像黑客。 这是我正在渲染到 DOM 中的组件

        import React, {Component} from 'react';
    
        class Search extends Component {
            constructor(props){
                super(props);
                this.state = {
                    value: ''
                }
            }
    
            handleChange(event){
                this.setState({value: event.target.value})
            }
    
            render() {
                return (
                    <div className='input-group'>
                        <input ref='input' type='text' className='form-control' placeholder='Enter stock ticker' value={this.state.value}
                        onChange={this.handleChange}/>
                        <span className='input-group-btn'>
                            <button className='btn btn-primary' type='submit' 
                            onClick={() => this.props.onClick(this.state.value)}>
                                Add
                            </button>
                        </span>
                    </div>
                )
            }
        }
    
        Search.propTypes = {
            onClick: React.PropTypes.func.isRequired
        }
    
        export default Search;
    

    这是接受用户输入的单元测试。不包括验证

    it('accepts user input from the search button', () => {
            let search_term;
            const clickHandler = (term) => search_term = term;
    
            const component = renderIntoDocument(
                <Search onClick={clickHandler} />
            );
    
            component.state.value = 'FB';
    
            expect(component.state.value).to.equal('FB');
        })
    

    我对此不太确定的原因是因为我明确设置了 component.state.value = 'FB' 然后检查它是否是,它将是。但这是我最接近验证值实际发生变化的方法,因为尝试运行

    Simulate.change(component, {state: {value: 'FB'}});
    

    抛出错误

    TypeError: 无法读取属性 '__reactInternalInstance$gvviufwbzvqrhtud00vbo6r' 未定义

    根据 React 文档 (https://facebook.github.io/react/docs/test-utils.html#simulate) 尝试以下操作

    it('accepts user input from the search button', () => {
        let search_term;
        const clickHandler = (term) => search_term = term;
    
        const component = renderIntoDocument(
            <Search onClick={clickHandler} />
        );
        const input = component.refs.input;
        input.value = 'FB';
        Simulate.change(input);
        expect(input.value).to.equal('FB');
        // component.state.value = 'FB';
        // expect(component.state.value).to.equal('FB');
    })
    

    返回错误

    TypeError: 无法读取未定义的属性“setState”

    大概是因为调用 Simulate 函数时必须设置状态,而输入 ref 只读取状态。

    如果有人对这些不同的错误有任何答案,或者甚至是模拟功能的工作原理(文档不是很有帮助),请分享。

    【讨论】:

      【解决方案2】:

      所以,我将添加另一个答案,因为我仍然希望得到关于我在之前的答案中提出的 Simulate 对象的问题的答案。

      我遇到的问题与我正在编写的测试无关,而是我没有将它绑定到 Search 容器内的 handleChange 方法。

      这是搜索容器的更新构造函数

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

      这是现在将通过的测试

      it('accepts user input from the search button', () => {
              let search_term;
              const clickHandler = (term) => search_term = term;
      
              const component = renderIntoDocument(
                  <Search onClick={clickHandler} />
              );
              const input = component.refs.input;
              input.value = 'FB';
              Simulate.change(component.refs.input);
              expect(input.value).to.equal('FB');
          })
      

      【讨论】:

        猜你喜欢
        • 2011-10-09
        • 2017-06-05
        • 1970-01-01
        • 1970-01-01
        • 2016-07-29
        • 1970-01-01
        • 2017-03-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多