React / Jest / Enzyme:如何测试添加文本以输入和检查该文本?

时间:2017-07-21 15:35:53

标签: javascript reactjs react-redux jestjs enzyme

我们有一个带有简单输入和提交按钮的表单。提交后,将在section.user-list内添加li。

点击ni并点击搜索按钮后,2 lis将进入视图,其中一个包含“Nick Sims”

enter image description here

enter image description here

然而,在运行下面的测试之后,视图从未改变,测试会选择默认的“搜索用户”字符串,该字符串应替换为新的lis。

注意,在我们的应用程序中,有一个调度函数调用Redux操作到SEARCH_USERS以返回用户列表,这可能是问题吗?

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(智能)

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

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

也尝试了这个,结果相同

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

1 个答案:

答案 0 :(得分:1)

这是一个过于复杂的测试,该操作会调度一个事件,然后通过Redux更新状态。

我们正在测试的内容需要分解为几个步骤。

  • 模拟假数据
  • 测试reducer中的操作
  • Enzyme不支持派遣的活动

https://github.com/airbnb/enzyme/blob/master/docs/future.md