2016-12-01 61 views
0

我有一個搜索欄,我想測試用戶輸入。我使用React渲染視圖,並使用Chai,Mocha和JSDom編寫測試。使用Mocha,Chai和JSDom嘲弄TDD for React的用戶輸入?

下面是簡單的測試,我已經寫到目前爲止

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)我想測試用戶沒有在搜索詞中輸入任何數字或特殊字符,字符串只需要字母表。

如何模擬這些測試?

回答

0

好的,所以我在一些調試後有答案。但是,這似乎有點黑客。 這裏是我渲染到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'}}); 

拋出Error

TypeError: Cannot read property '__reactInternalInstance$gvviufwbzvqrhtud00vbo6r' of undefined

嘗試以下根據陣營文檔(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: Cannot read property 'setState' of undefined

大概是因爲在調用Simulate函數時必須設置狀態,並且輸入參考只讀取狀態。

如果任何人對這些錯誤有任何答案,或者即使Simulate功能有效(文檔不是很好的幫助),也請分享。

0

所以,我要添加另一個答案,因爲我仍然喜歡我在之前的答案中提出的關於模擬對象問題的答案。

我遇到的問題與我正在編寫的測試無關,但事實上我沒有將它綁定到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'); 
    })