React/Jest/Enzyme: How to test adding text to input and checking for that text?

Viewed 2614

We have a form with a simple input and submit button. Upon submit, there will be li's added inside of the section.user-list.

After typing ni and clicking the Search button, 2 lis will enter the view, one of them containing "Nick Sims"

enter image description here

enter image description here

However after running the test below, the view never changed, the test picks up the default "Search for a user" string which should be replaced by the new lis.

Note, in our app, there is a dispatch function which calls a Redux action to SEARCH_USERS in order to return the user list, could this be the problem?

enter image description here

import React from 'react'
import { shallow, mount } from 'enzyme'
import toJson from 'enzyme-to-json'

import { UserListContainer } from './UserListContainer'

const userListContainer = mount(<UserListContainer />);

describe('<UserListContainer /> tests', () => {
    let wrapper;

    beforeAll(() => {
        wrapper = mount(<UserListContainer searchUser={() => {}} />);
    });

    it('Should contain an input', () => {
        expect(wrapper.find('input')).toHaveLength(1);
    });

    it('Should show User after a user searches', () => {
        expect(wrapper.find('input.input-user')).toHaveLength(1);
        wrapper.find('input.input-user').simulate('keydown', { which: 'r' });
        wrapper.find('input.input-user').simulate('keydown', { which: 'o' });

        const text = wrapper.find('input.input-user').text();
        const value = wrapper.find('input.input-user').get(0).value;

        console.log('value:', value)
        console.log('text:', text)

        wrapper.find('button.btn-blue').simulate('click');

        expect(wrapper.find('.user-population li').text()).toEqual('Nick Sims');
    });
});

UserListContainer (Smart)

import React, { Component } from "react"
import { connect } from 'react-redux'
import { UserList } from '../../components'
import { searchUser } from '../../actions'

export class UserListContainer extends Component {
    constructor(props) {
        super(props);
    }

    onFormSubmit(e, user) {
        e.preventDefault();
        this.props.searchUser(user)
    }

    render() {
        return (
            <div className='users-container'>
                <UserList
                    users={this.props.users}
                    lastUserSearched={this.props.lastUserSearched}
                    onFormSubmit={this.onFormSubmit.bind(this)}
                />
            </div>
        )
    }
}

const mapStateToProps = (state) => {
    return {
        users: state.usersReducer.users,
        lastUserSearched: state.usersReducer.lastUserSearched
    }
}

const mapDispatchToProps = (dispatch) => {
    return {
        searchUser: (user) => {dispatch(searchUser(user))},
    }
}

const userList = UserListContainer;
export default connect(mapStateToProps, mapDispatchToProps)(userList)

UserList (Dumb)

import React from 'react'
import { Link } from 'react-router-dom'

export default class UserList extends React.Component {
  constructor(props) {
    super(props);
  }

  onFormSubmit(e) {
    const value = this.input.value;
    this.props.onFormSubmit(e, value);
  }

  populateUsers() {
    const users = this.props.users;
    if(!this.props.lastUserSearched) {
      return <li>Search for a user</li>
    }

    { /* Search / Auto Suggest functionality */ }
    const regex = this.props.lastUserSearched;
    let re = new RegExp(regex, "gi");

    let filteredUsers = users.filter(v => {
      if(v.name.match(re)) {
        return v;
      }
      return;
    });

    if(filteredUsers.length < 1) {
      return <li>No users found with that name</li>
    }

    return filteredUsers.map(x => {
      return (
        <li key={x._id}>
          <Link to="#" className="user-link">
            { x.name }
          </Link>
        </li>
      )
    });
  }

  render () {
    return (
      <section className="user-list">
        <form onSubmit={ this.onFormSubmit.bind(this) }>
          <label>
            <input
              type="text"
              className="input-user"
              placeholder="Search.."
              ref={(ref) => { this.input = ref; }}
            />
            <button className="btn-blue" type="submit">Search</button>
          </label>
        </form>
        <h2>User List</h2>
        <ul className="user-population">
          { this.populateUsers() }
        </ul>
      </section>
    )
  }
}

Also tried this, same results

// wrapper.find('input.input-user').simulate('input', { target: { value: 'ni' } });
wrapper.find('input.input-user').simulate('submit', { target: { value: 'ni' } });
1 Answers
Related