Ad

How To Test Onclick Api Call With React

- 1 answer

I have 3 react components and when the user clicks on USER_CARD in header then an api is called and the response is displayed in TwitterList component. I have no experience with unit testing, so what are the unit test needs to be done and how? I have read about enzyme and jest but not sure about the implementation.

Fews things I understand here that I need to test the click and also check if the api is responding with any data or not.

Please help me understand how to do this?

    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? 
Ad

Answer

wrote this code by heart (so not tested) but should give you the idea:

  1. unit test the onClick:

shallow the USER_CARD with enzyme like this, pass mock function, trigger click and check if the function was called with expected arguments:

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")
  1. unit test the API

a) either mock the whole Http and then use mock return value, shallow your component and trigger your _getUserTweets like in 1. where I showed you how to test your onClick and then find your TweetList if data was set accordingly, here the mocking part of API:

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()
        })
    }
}))

b) dont mock Http but spyOn + mockImplementation:

const getSpy = jest.spyOn(Http, 'get').mockImplementation(() => ...) // here your mock implementation

important! restore at end of test:

getSpy.mockRestore()
Ad
source: stackoverflow.com
Ad