使用Jest进行组件测试

时间:2018-09-20 08:08:04

标签: javascript reactjs unit-testing jestjs

嗨,我是Jest和Java Script的新手。我要对其中一个组件执行测试。

我要检查管理员是否看到以下句子:

“请选择一个用户以显示他/她的捐款:”

我的建议是:

const sentence = "Please select a user to show his/her donations:"
it('Shows: Please select a user to show his/her donations:', () => {
  const admin = shallow(<AdminViewComponent />);
  const wantedSentence = admin.find(sentence);
  expect(wantedSentence).toEqual(true);
});

但是由于这行不通,所以我想再提出一条建议。

这是我要测试的组件:

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Typeahead } from 'react-bootstrap-typeahead'; // ES2015
import axios from 'axios';
import { WholeScreen } from './WholeScreenComponent.js';

export class AdminViewComponent extends Component {

  constructor(props) {
    super(props);

    this.state = {
      emailList: [],
      selectedUser: "",
      SelectedUserDonationData: {}
    };

    this._handleChange = this._handleChange.bind(this);
  }

  getInitialState() {
    return {
      // [{}] is weird, either use undefined (or [] but undefined is better).
      // If you use [], you loose the information of a "pending" request, as 
      // you won't be able to make a distinction between a pending request, 
      // and a response that returns an empty array
      emailList: undefined,
      selectedUser: undefined,
      SelectedUserDonationData: undefined
    }
  }
  componentDidMount() {
    this.setState({ emailList: undefined });
    return axios.get('./api/user/', {
      headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer ' + this.props.token
      }
    }).then(response => {
      const emailListResult = response.data;
      this.setState({ emailList: emailListResult });

    }).catch(function (error) {
      console.log(error);
    });
  }

  _handleChange(SelectedUser) {
    this.setState({ selectedUser: SelectedUser, selectedUserDonationData: undefined });


    axios.get('./api/user/' + SelectedUser + '/',
      {
        headers: {
          'Content-Type': 'application/json',
          'Authorization': 'Bearer ' + this.props.token
        }
      }).then(response => {
        const selectedUserDonationDataResponse = response.data;
        this.setState({ selectedUserDonationData: selectedUserDonationDataResponse });
        console.log(selectedUserDonationDataResponse);

      }).catch(function (error) {
        console.log(error);
      });

  }

  render() {
    var adminView;
    if (!this.state.emailList) {
      adminView = <div>Please wait while we retrieve all users...</div>
    }
    else {
      adminView = (
        <div>
          <div>
            Please select user to show his/her donations
          </div>
          <Typeahead
            placeholder="Select user email..."
            onChange={this._handleChange}
            options={this.state.emailList} />
        </div>
      );
    }

    var selectedUserData;
    if (this.state.selectedUserDonationData) {
      selectedUserData = (
        <div className="AdminViewData">
          <h4 className="DtatOf">
            Showing donations of: {this.state.selectedUser}
          </h4>
          <WholeScreen data={this.state.selectedUserDonationData.DonationsList} />
        </div>
      );
    }

    var url = "./api/user/";
    return (
      <div className="AdminView">
        {adminView}
        {selectedUserData}
      </div>
    );
  }
}

我要测试的行位于render()函数中

adminView = <div>Please wait while we retrieve all users...</div>

2 个答案:

答案 0 :(得分:1)

如果将可选属性添加到DOM节点,会更容易。

  it('Shows: Please select a user to show his/her donations:', () => {
    const admin = mount(<AdminViewComponent />);
    const actualText = admin.find("[data-id='someSelector']").text();
    const expectedText = "Please select a user to show his/her donations";

    expect(actualText).toEqual(expectedText);
  });

  /*
     Alternately you could use a snapshot test as this would remove 
     the need to copy the text into the test
  */


  it('Shows: Please select a user to show his/her donations:', () => {
    const admin = mount(<AdminViewComponent />);
    const actualText = admin.find("[data-id='someSelector']").text();

    expect(actualText).toMatchSnapshot();
  });

答案 1 :(得分:1)

由于您的div元素上没有类或ID,因此使用.find()很难检索它。幸运的是,您还可以使用.containsMatchingElement(node)来检查Component是否包含一个元素而不是一个选择器。换句话说,您可以执行以下操作:

  const elementToCheck = "<div> Please select user to show his/her donations </div>"
  it('Shows: Please select a user to show his/her donations:', () => {
    const admin = shallow(<AdminViewComponent />);
   expect(admin.containsMatchingElement(elementToCheck)).toEqual(true);
  });

详细了解.containsMatchingElement here