首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >用于reactjs中的输入更改和按钮的jest测试用例

用于reactjs中的输入更改和按钮的jest测试用例
EN

Stack Overflow用户
提问于 2018-05-30 03:23:47
回答 1查看 2.1K关注 0票数 0

我对jest非常陌生,所以我不知道如何继续使用jest。我已经使用jest编写了测试用例,用于更改时的输入和以下组件的按钮单击。但它失败了。“Method”props“的问题是只能在单个节点上运行。发现0。”请帮帮我

代码:

代码语言:javascript
复制
import React from 'react';
import { Col } from 'react-bootstrap';

class FITB extends React.Component {
  constructor(props) {
    super(props);
    this.String = String;
    this.defaultTextSize = 8;
    this.state = {
      inputList: [],
      splitList: [],
      count: 0,
      isValid: false
    };
    this.onInputChange = this.onInputChange.bind(this);
    this.onClickSend = this.onClickSend.bind(this);
    this.checkInputValidations = this.checkInputValidations.bind(this);
  }

  componentDidMount() {
    this.initialize();
  }

  onInputChange(index) {
    return (event) => {
      const inputList = this.state.inputList;
      let isValid = true;
      inputList[index] = event.target.value;
      if (!this.isValidInput(inputList[index])) {
        isValid = false;
      }
      this.setState({
        inputList,
        isValid
      });
      // console.log('onInputChange fib state', this.state);
    };
  }

  onClickSend() {
    const {
      splitList,
      inputList,
      count
    } = this.state;
    // console.log('onClickSend fib before state', this.state);
    const onReply = this.props.onReply;
    let fullText = '';
    splitList.map((text, index) => {
      fullText += text;
      if ((index < count - 1) && inputList[index]) {
        fullText += inputList[index];
      }
      return true;
    });

    if (onReply) {
      onReply(fullText);
    }
    // console.log('onClickSend fib after state', this.state);
  }

  isValidInput(text) {
    const regex = /^[\u0020-\u007e]*$/;
    const replaceChar160RegExp = new RegExp(this.String.fromCharCode(160), 'g');
    return regex.test(text.replace(replaceChar160RegExp, ' '));
  }

  initialize() {
    let text = '';
    this.props.messages.map((element) => {
      if (element.type && (typeof element.type === 'string') && (element.type === 'FILL_IN_THE_BLANK')) {
        text = element.message;
      }
      // console.log('inside fib', text);
      return text;
    });
    const splitList = text.split(/_+/g);
    this.setState({
      splitList,
      count: splitList.length
    });
    // console.log('init fib state', this.state);
  }

  checkInputValidations() {
    const {
      inputList,
      count,
      isValid
    } = this.state;
    let i;
    let flag = false;
    for (i = 0; i < count - 1; i += 1) {
      if (!inputList[i] || inputList[i].trim() === '') {
        flag = true;
      }
    }
    // console.log('checkInputValidations', this.state);
    return flag || !isValid;
  }

  render() {
    const {
      splitList,
      count,
      inputList
    } = this.state;
    // console.log('reder fitb', this.state);
    return (
      <Col lg={12} className="rply-block">
        <Col lg={11} className="textarea-block">
          <div className="fitb-wrap">
            { splitList && splitList.map((item, index) => (
              <span>
                <span className="fitb-text">{item}</span>
                { (index < count - 1) && (
                  <input
                    className="fitb-input"
                    type="text"
                    maxLength="40"
                    size={(inputList[index] && inputList[index].length > this.defaultTextSize && inputList[index].length) || this.defaultTextSize}
                    value={inputList[index]}
                    onChange={this.onInputChange(index)}
                    autoFocus={index === 0}
                    aria-describedby={count > 1 ? `Missing word ${index + 1} of ${count - 1}` : 'Missing word'}
                    aria-label="Fill in missing words"
                  />
                )}
              </span>
            ))}
          </div>
        </Col>
        <Col lg={1} className="">
          <button
            className="btn-info-dm"
            role="button"
            tabIndex="0"
            onClick={this.onClickSend}
            disabled={this.checkInputValidations()}
          >Send</button>
        </Col>
      </Col>
    );
  }
}

FITB.propTypes = {
  onReply: React.PropTypes.isRequired,
  messages: React.PropTypes.array
};

export default FITB;

用于输入的测试文件并单击按钮

代码语言:javascript
复制
import React from 'react';
import FITB from '../components/dialogManager/fitb';
import { shallow } from 'enzyme';
import renderer from 'react-test-renderer';

describe('FITB', () => {
  let component;
  const mockFn = jest.fn();
  beforeEach(() => {
    component = shallow(<FITB onReply={mockFn} />);
  });
  test('Should initialize the FITB content', () => {
    expect(component.find('.rply-block')).toHaveLength(1);
  });

  test('Should have been called send', () => {
    component.find('.btn-info-dm').simulate('click');
    expect(mockFn).toHaveBeenCalled();
  });
  test('Should render the text box', () => {
    expect(component.state().inputList).toEqual([]);
    expect(component.state().isValid).toEqual(false);
    // expect(component.find('input.fitb-input')).toBeDefined();
    console.log('state== ', component.state());
    console.log('input == ', component.find('.fitb-input'));
    component.find('.fitb-input').simulate('change', { target: { value: 'Qualitative data includes detailed interviews, direct _____, and historical records.' } });
    console.log('fitb-input onchange== ', component.find('.fitb-input'));
    expect(component.state().inputList).toEqual('Qualitative data includes detailed interviews, direct _____, and historical records.');
    expect(component.state().isValid).toEqual(true);
  });
  // test('Should check the input label', () => {
  //   const expectedFitbTextLabel = 'Fill in missing words';
  //   const fitbTextList = [];
  //   console.log('span fitb txt== ', component.find('.fitb-text').instance().label);
  //   component.find('.fitb-text').map((elem) => {
  //     fitbTextList.push(elem.text().trim());
  //   });
  //   expect(component.find('.fitb-text').instance().label).toEqual(expectedFitbTextLabel);
  // });
  test('Should render the fitbText ', () => {
    const expectedFitbText = 'Qualitative data includes detailed interviews, direct _____, and historical records.';
    const fitbTextList = [];
    console.log('span fitb txt== ', component.find('.fitb-text').text());
    // fitbTextList.push(expectedFitbText.split(/_+/g));
    // console.log('fitbTextList= ', fitbTextList);
    component.find('.fitb-text').map((elem) => {
      fitbTextList.push(elem.text().trim());
    });
    expect(fitbTextList).toEqual(expectedFitbText);
  });
  test('Should check the fitbText ', () => {
    const expectedFitbText = 'Qualitative data includes detailed interviews, direct _____, and historical records.';
    const fitbTextList = [];
    fitbTextList.push(expectedFitbText.split(/_+/g));
    expect(component.state().inputList).toEqual([]);
    console.log('input list init== ', component.state().inputList);
    component.find('input.fitb-input').simulate('change', { target: { value: 'test' } });
    console.log('input list== ', component.state().inputList);
    // component.find('input').instance().onInputChange(0);
    // expect(component.state().inputList).toEqual('test');
  });
});

对于打开的另一个组件按钮,单击以发送详细信息

代码语言:javascript
复制
import React from 'react';

class ReplyButtons extends React.Component {
  constructor(props) {
    super(props);
    this.replyBtnWrap = '';
    this.replyBtnList = '';
    this.state = {
      list: [],
      isLeftArrowEnabled: false,
      isRightArrowEnabled: false
    };

    this.onClickLeftArrow = this.onClickLeftArrow.bind(this);
    this.onClickRightArrow = this.onClickRightArrow.bind(this);
    this.onClickReplyBtn = this.onClickReplyBtn.bind(this);
  }

  componentDidMount() {
    this.initializeList();
  }

  componentDidUpdate() {
    this.checkElementOffset();
  }

  onClickRightArrow() {
    const wrapElement = this.replyBtnWrap;
    const listElement = this.replyBtnList;
    const wrapWidth = wrapElement.offsetWidth;
    const listWidth = listElement.offsetWidth;
    let listLeft = wrapElement.scrollLeft;
    let listOverflowWidth = 0;
    listLeft += 400;
    listOverflowWidth = listWidth - listLeft;
    if (listOverflowWidth < 0) {
      listLeft = listWidth - wrapWidth;
    }
    wrapElement.scrollLeft = listLeft;
    this.checkElementOffset();
  }

  onClickLeftArrow() {
    const wrapElement = this.replyBtnWrap;
    let listLeft = wrapElement.scrollLeft;

    listLeft -= 400;

    if (listLeft < 0) {
      listLeft = 0;
    }
    wrapElement.scrollLeft = listLeft;
    this.checkElementOffset();
  }

  onClickReplyBtn(item) {
    return () => {
      const onReply = this.props.onReply;
      if (onReply) {
        onReply(item);
      }
    };
  }

  checkElementOffset() {
    const wrapElement = this.replyBtnWrap;
    const listElement = this.replyBtnList;
    const wrapWidth = wrapElement.offsetWidth;
    const listWidth = listElement.offsetWidth;
    const listLeft = wrapElement.scrollLeft;
    let listOverflowWidth = 0;
    let isLeftArrowEnabled = false;
    let isRightArrowEnabled = false;
    if (listLeft > 0) {
      isLeftArrowEnabled = true;
    }
    listOverflowWidth = listWidth - listLeft - wrapWidth;
    if (listOverflowWidth > 0) {
      isRightArrowEnabled = true;
    }
    if (this.state.isLeftArrowEnabled !== isLeftArrowEnabled || this.state.isRightArrowEnabled !== isRightArrowEnabled) {
      this.setState({
        isLeftArrowEnabled,
        isRightArrowEnabled
      });
    }
  }

  initializeList() {
    // this.setState({
    //   list: [{
    //     type: 'MENU_ITEM',
    //     text: 'what is quantitative research?',
    //     return_value: 'what is quantitative research?'
    //   }, {
    //     type: 'MENU_ITEM',
    //     text: 'what is mixed method research?',
    //     return_value: 'what is mixed method research?'
    //   }, {
    //     type: 'MENU_ITEM',
    //     text: 'what is qualitative research?',
    //     return_value: 'what is qualitative research?'
    //   }, {
    //     type: 'MENU_ITEM',
    //     text: 'I had a different question',
    //     return_value: 'I had a different question'
    //   }, {
    //     type: 'MENU_ITEM',
    //     text: 'That was actually my answer',
    //     return_value: 'That was actually my answer'
    //   }]
    // });
    const replyButtonText = [];
    // console.log('reply btns props = ', this.props);
    if (this.props.messages) {
      this.props.messages.map((element) => {
        if (element.type && (typeof element.type === 'string') && (element.type === 'MENU_ITEM')) {
          replyButtonText.push(element);
        }
        return this.setState({ list: replyButtonText });
      });
    }
  }

  render() {
    const btnList = this.state.list;
    const {
      isLeftArrowEnabled,
      isRightArrowEnabled
    } = this.state;
    return (
      <div className="r-wrap">
        { isLeftArrowEnabled && (
          <button className="r-btn-left-arrow" onClick={this.onClickLeftArrow} role="button" tabIndex="0">
            <i className="glyphicon glyphicon-menu-left" />
          </button>
        )}
        <div className="r-btn-wrap" ref={(e) => { this.replyBtnWrap = e; }}>
          <div className="r-btn-list" ref={(e) => { this.replyBtnList = e; }}>
            {
              btnList && btnList.map(btnItem => <button
                className="r-btn"
                role="button"
                tabIndex="0"
                onClick={this.onClickReplyBtn(btnItem)}
                title={btnItem.text}
              >{btnItem.text}</button>)
            }
          </div>
        </div>
        { isRightArrowEnabled && (
          <button className="r-btn-right-arrow" onClick={this.onClickRightArrow} role="button" tabIndex="0">
            <i className="glyphicon glyphicon-menu-right" />
          </button>
        )}
      </div>
    );
  }
}

ReplyButtons.propTypes = {
  onReply: React.PropTypes.isRequired,
  messages: React.PropTypes.array
};

export default ReplyButtons;

测试文件:

代码语言:javascript
复制
import React from 'react';
import ReplyButtons from '../components/dialogManager/replybuttons';
import { shallow } from 'enzyme';
import renderer from 'react-test-renderer';

const mockOutputObj = [{
  type: 'MENU_ITEM',
  text: 'what is quantitative research?',
  return_value: 'what is quantitative research?'
}, {
  type: 'MENU_ITEM',
  text: 'what is mixed method research?',
  return_value: 'what is mixed method research?'
}];

describe('ReplyButtons', () => {
  let component;
  const mockFn = jest.fn();
  beforeEach(() => {
    component = shallow(<ReplyButtons onReply={mockFn} />);
  });

  test('Should initialize the ReplyButtons content', () => {
    expect(component.find('.r-wrap')).toHaveLength(1);
  });

  test('Should check the ReplyButtons click', () => {
    console.log('r-btn==> ', component.find('button.r-btn'));
    component.find('.r-btn').simulate('click');
    expect(mockFn).toHaveBeenCalled();
  });
});

请帮帮我。

EN

回答 1

Stack Overflow用户

发布于 2018-06-01 05:03:41

我认为错误的发生是因为最后一个测试用例中的选择器

代码语言:javascript
复制
component.find('button.r-btn')

引用通过迭代ReplyButtons组件中的this.state.list生成的按钮

并且您没有提供适当的“消息”来触发对列表的馈送

尝试使用如下消息实例化ReplyButtons

代码语言:javascript
复制
beforeEach(() => {
    component = shallow(<ReplyButtons onReply={mockFn} messages={['1','2']}/>);
});

这应该是可以的(顺便说一句,这里没有错误堆栈是非常不舒服的,可能还有其他问题)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50591533

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档