首页 > 解决方案 > 酶:模拟onSubmit时返回未定义的值

问题描述

我正在尝试模拟提交表单的方式。所以总结一下,当用户在textarea'字段中键入时,组件必须更新,然后用户按下提交按钮,组件再次更新。我希望用户成功提交后textarea中填写的值会为空。但没想到返回值是undefined.

评论框.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;

评论框.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('');
})

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

标签: reactjsjestjsenzyme

解决方案


我没有看到任何会使测试失败的东西......除了不包括this.setState({ comment: "" });handleSubmit回调中。

如果您使用state,则必须手动重置它(或者如果组件卸载,则它会state自动丢失)。React 通过操纵一个虚拟的DOM. 然后,您利用state来操作此虚拟中的元素DOM。由于您正在阻止页面刷新 ( e.preventDefault),因此state会按预期持续存在。

工作示例(单击Tests选项卡——选项卡旁边Browser——运行测试):

编辑评论框测试


组件/评论框

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;

组件/评论框/__tests__/评论框.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("");
  });
});

推荐阅读