如何使用React测试onclick api调用

时间:2019-08-07 12:55:37

标签: reactjs jestjs enzyme

我有3个React组件,当用户单击标题中的USER_CARD时,将调用一个api,并且响应将显示在TwitterList组件中。我没有单元测试的经验,所以需要进行哪些单元测试,以及如何进行?我已经读过关于酶和玩笑的文章,但不确定执行情况。

我了解到的一些问题,我需要测试点击并检查api是否响应任何数据。

请帮助我了解如何执行此操作?

    import React ,{Component}from 'react'

    // Import all contianers here
    import Header from './containers/header'
    import TweetList from './containers/tweetlist'

    // Import all services here
    import Http from './services/http'

    import './App.css'

    class App extends Component {

      constructor() {
        super()

        this.state = {
          data: [],
          isTop: true,
          userName: ''
        }
      }

      _getUserTweets = (user) => {
        console.log(user)
        if (user !== undefined && user !== '') {
          Http.get('/' + user)
          .then(response => {
            if (response.data.length > 0) {
              this.setState((prevState) => {
                return {
                  ...prevState,
                  data: response.data,
                  userName: user
                }
              })
            }
          })
          .catch(error => {
            console.log(error)
          })
        } else {
          console.log('No user found!!')
        }
      }

      render() {
        const {data, userName} = this.state
        return (
          <div className="app_container">
            <Header getUserTweets={this._getUserTweets} />
            <TweetList data={data} user={userName} />
          </div>
        );
      }
    }

    export default App;



    import React, {Component} from 'react'

    class TweetList extends Component {

        constructor() {
            super()

            this.state = {
                tweets: []
            }
        }

        componentWillReceiveProps(nextProps) {

            if (nextProps.data.length > 0) {
                this.setState((prevState) => {
                    return {
                        ...prevState,
                        tweets: nextProps.data
                    }
                })
            }
        }

        render() {
            const {tweets} = this.state
            return (
                <div>
                    {
                        tweets.length > 0
                        &&
                        tweets.map((currentValue, index) => {
                            return (
                                <p>{currentValue.full_text}</p>
                            )
                        })
                    }
                </div>
            )
        }
    }

    export default TweetList



    import React, {Component} from 'react'
    import './style.css'

    const USER_CARD = ({userName, onClickHandler}) => {
        return (
            <p onClick={() => onClickHandler(userName)}>{userName}</p>
        )
    }

    class Header extends Component {

        componentWillMount() {
            if (process.env.REACT_APP_USER_LIST !== undefined && process.env.REACT_APP_USER_LIST.split(',').length > 0) {
                this.props.getUserTweets(process.env.REACT_APP_USER_LIST.split(',')[0])
            }
        }

        _getUserTweets = (userName) => {
            this.props.getUserTweets(userName)
        }

        render() {
            return(
                <div className="header_container">
                    {process.env.REACT_APP_USER_LIST !== undefined
                    &&
                    process.env.REACT_APP_USER_LIST.split(',').length > 0
                    &&
                    process.env.REACT_APP_USER_LIST.split(',')
                    .map((currentValue, index) => {
                        return (
                            <USER_CARD userName={currentValue} key={`user-card-${index}`}
                                onClickHandler={this._getUserTweets} />
                        )
                    })}
                </div>
            )
        }
    }

    export default Header

If the user click on the USER_CARD in Header component then we call an api to get the results.

What are the different unit testing that I can do and how to do it? 

1 个答案:

答案 0 :(得分:0)

请认真编写此代码(因此未经测试),但应能为您提供想法:

  1. 单元测试onClick:

用这样的酶使USER_CARD变浅,传递模拟函数,触发单击并检查是否使用预期参数调用了该函数:

DataContext
  1. 对API进行单元测试

a)要么模拟整个Http,然后使用模拟的返回值,将组件变浅,然后像1中那样触发_getUserTweets。在这里,我向您展示了如何测试onClick,然后在数据被相应地设置的情况下找到了TweetList,这里API的模拟部分:

Value

b)不模拟Http,但spyOn +模拟实现:

const handlerMock = jest.fn()
const wrapper = shallow(<USER_CARD userName="foo" onClickHandler={handlerMock}/>)

wrapper.find('p').simulate('click') // or wrapper.find('p').prop('onClick)()

expect(handlerMock).toHaveBeenCalledTimes(1)
expect(handlerMock).toHaveBeenCalledWith("foo")

重要!在测试结束时恢复:

import Http from './services/http'
jest.mock('./services/http')

const mockResponse = foobar; // response expected from your call
Http.get.mockReturnValue(({
    then: (succ) => {
        succ(mockResponse)
        return ({
            catch: jest.fn()
        })
    }
}))