酶:模拟onSubmit时,值返回未定义

时间:2019-05-08 04:47:23

标签: reactjs jestjs enzyme

我正在尝试模拟表单的提交方式。因此,总结一下,当用户在textarea字段中键入内容时,必须更新组件,然后用户按下Submit按钮,然后再次更新组件。我希望用户成功提交后,textarea中填充的值将为空。但是意外地,返回值是undefined

CommentBox.js

import React from 'react';

class CommentBox extends React.Component {
    state = {
        comment: ''
    }

    handleChange = event => {
        this.setState({
            comment: event.target.value
        })
    }

    handleSubmit = event => {
        event.preventDefault();
    }

    render() {
        return (
            <form onSubmit={this.handleSubmit}>
                <h4>Add a comment</h4>
                <textarea onChange={this.handleChange} value={this.state.comment} />
                <div>
                    <button>Submit Comment</button>
                </div>
            </form>
        )
    }
}

export default CommentBox;

CommentBox.text.js

import React from 'react';
import { mount } from 'enzyme';
import CommentBox from 'components/CommentBox';

let wrapped;

beforeEach(() => {
    wrapped = mount(<CommentBox />);
})

afterEach(() => {
    wrapped.unmount();
})

it('when form is submitted, text area gets emptied', () => {
    wrapped.find('textarea').simulate('change', {
        target: { value: 'new comment' }
    })

    wrapped.update();
    wrapped.find('form').simulate('submit', {
        preventDefault: () => {}
    });
    wrapped.update();

    expect(wrapped.find('textarea').prop('value')).toEqual('');
})

我希望输出将通过,但实际输出是value返回未定义,因此测试失败。

3 个答案:

答案 0 :(得分:1)

除了没有在this.setState({ comment: "" });回调中包含handleSubmit之外,我没有看到任何会导致测试失败的事情。

如果您使用state,则必须手动将其重置(或者,如果卸下组件,则它会自动丢失state)。 React通过操纵虚拟DOM来工作。然后,您利用state来操纵该虚拟DOM中的元素。由于您要阻止页面刷新(e.preventDefault),因此state会按预期保留。

工作示例(单击Tests标签旁边的Browser标签—运行测试):

Edit CommentBox Testing


组件/注释框

import React, { Component } from "react";

class CommentBox extends Component {
  state = { comment: "" };

  handleChange = ({ target: { value } }) => {
    this.setState({ comment: value });
  };

  handleSubmit = e => {
    e.preventDefault();

    console.log("submitted comment: ", this.state.comment);

    this.setState({ comment: "" });
  };

  render = () => (
    <div className="app">
      <form onSubmit={this.handleSubmit}>
        <h4>Add a comment</h4>
        <textarea
          className="uk-textarea"
          onChange={this.handleChange}
          value={this.state.comment}
        />
        <div className="button-container">
          <button type="submit" className="uk-button uk-button-primary">
            Submit Comment
          </button>
        </div>
      </form>
    </div>
  );
}

export default CommentBox;

components / CommentBox / __ tests __ / CommentBox.test.js

import React from "react";
import { mount } from "enzyme";
import CommentBox from "../index";

describe("Comment Box", () => {
  let wrapper;
  beforeEach(() => {
    wrapper = mount(<CommentBox />);
  });

  afterEach(() => {
    wrapper.unmount();
  });

  it("when form is submitted, text area gets emptied", () => {
    wrapper.find("textarea").simulate("change", {
      target: { value: "new comment" }
    });

    expect(wrapper.find("textarea").prop("value")).toEqual("new comment");

    wrapper.find("form").simulate("submit", {
      preventDefault: () => {}
    });

    expect(wrapper.find("textarea").prop("value")).toEqual("");
  });
});

答案 1 :(得分:0)

handleChange = (e) => {
 if(e.keyCode == 13 && e.shiftKey == false) {
  e.preventDefault();
  this.myFormRef.submit();
  }
}

render() {
  return (
    <form ref={el => this.myFormRef = el}  >
            <h4>Add a comment</h4>
            <textarea onKeyDown={this.handleChange} value={this.state.comment} 
             />
            <div>
                <button type="submit">Submit Comment</button>
            </div>
        </form>

 );
}

您可以在Enter上这样做

答案 2 :(得分:0)

您可以尝试以下方法:

import React from 'react';

class CommentBox extends React.Component {
    //adding initVal for setting initial value in textbox
    // and playing with it until the form submits
    state = {
        comment: '',
        initVal: ''
    }

    handleChange = event => {
        //on change in textfield, updating initVal with the typed text
        this.setState({
            initVal: event.target.value
        })
    }

    handleSubmit = event => {
        //finally on submission comment is updated with entered value
        //which you may use it for further operations
        //and initVal is set back to empty '' for setting textfield value as empty 
        //field
        this.setState({
            comment: this.state.initVal
            initVal: ''
        })
        //event.preventDefault();
    }

    render() {
        return (
            <form onSubmit={this.handleSubmit}>
                <h4>Add a comment</h4>
                //changes here
                <textarea onChange={this.handleChange} value={this.state.initVal} />
                <div>
                    <button>Submit Comment</button>
                </div>
            </form>
        )
    }
}

export default CommentBox;