【问题标题】:State is undefined when simulating click in react component test在反应组件测试中模拟单击时状态未定义
【发布时间】:2017-02-22 05:06:39
【问题描述】:

我一直在尝试测试我的方法 handleFormSubmit() 的行为。单击提交时,应触发调用。在我添加下面列出的两行之前,这绝对可以正常工作。似乎酶是在更新上下文还是不调用构造函数?

任何帮助,非常感谢。我已尽我所能保持帖子简短。

失败的行 - 状态未定义

data.username = this.state.username.trim();
data.password = this.state.password.trim();

组件:

从“反应”导入反应;

// Renders login form.
export default class LoginView extends React.Component {
  static propTypes = {
    model: React.PropTypes.object.isRequired,
    params: React.PropTypes.object.isRequired
  }

  constructor(props) {
    super(props);
    this.state = {
      username: '',
      password: ''
    };
  }

  handleUsernameChange(event) {
    this.setState({error: false, username: event.target.value});
  }

  handlePasswordChange(event) {
    this.setState({error: false, password: event.target.value});
  }

  handleFormSubmit(event) {
    event.preventDefault();

    let failureMsg = {},
      data = this.props.params,
      options = {
        success: (response) => {
          if (response.attributes.successfulLogin) {
            window.location = this.props.params.redirect +
              '?authenticationToken=' + response.get('authenticationToken') +
              this.createParams();
          } else {
            throw Error('Helpful error');
          }
        },
        error: () => {
          throw Error('Helpful error');
        }
      };

    // PROBLEM LINES!
    data.username = this.state.username.trim();
    data.password = this.state.password.trim();

    if (this.state.username && this.state.password && this.state.terms) {
      this.props.model.save(data, options);
    } else {
      this.setState({
        error: true,
        errorMessage: !this.state.username || !this.state.password ? LoginConstants.LOGIN.BLANK_INPUT : LoginConstants.LOGIN.BLANK_TERMS
      });
    }
  }

  render() {
    return (
      <form>
        <input type="text" ref="username" id="username" placeholder="Customer ID" onChange={this.handleUsernameChange.bind(this)} maxLength={75} value={this.state.username} />
        <input type="password" ref="password" id="password" placeholder="Password" onChange={this.handlePasswordChange.bind(this)} maxLength={75} value={this.state.password} />
        <button type="submit" ref="login" id="login" className="Button Button--primary u-marginT-md" onClick={this.handleFormSubmit.bind(this)}>LOGIN</button>
      </form>
    );
  }
}

单元测试:

  import React from 'react';
  import { mount } from 'enzyme';
  import LoginView from './LoginView';

  describe('Login screen', () => {
    let mountedComp;

    beforeAll(() => {
      mountedComp = mount(<LoginView />);
    });

    it('should show error if submitted blank', () => {
      mountedComp.instance().state = {
        username: '',
        password: ''
      };

      expect(mountedComp.find('#js-errorMessage').length).toEqual(0);
      mountedComp.ref('login').simulate('click', { preventDefault: () => undefined, state: {} });
      expect(mountedComp.find('#js-errorMessage').length).toBeGreaterThan(0);
    });
  });

【问题讨论】:

    标签: javascript reactjs jestjs enzyme


    【解决方案1】:

    尝试将您的 onClick 函数绑定到 &lt;form onClick={this.handleFormSubmit.bind(this)} &gt;

    【讨论】:

    • 不走运 - 类型错误:无法设置未定义的属性“用户名”
    【解决方案2】:

    看起来您的“this.state: 超出范围。考虑添加

    var _self = this;
    

    并使用

     _self.state.username.trim();
     _self.state.password.trim();
    

    【讨论】:

    • 不走运 - 类型错误:无法设置未定义的属性“用户名”
    【解决方案3】:

    我认为问题的根源可能在于这一行:

    let data = this.props.params
    

    在 JavaScript 中,它不会通过值将 this.props.params 对象复制到 data 对象,而是通过引用。它将为datathis.props.params 设置相同的引用——这意味着如果您更改data 的内容,它将反映在this.props.params 中,反之亦然。 所以你实际上是在改变应该是不可变的props

    您应该创建一个浅拷贝,例如像这样:

    let data = Object.assign({}, this.props.params)
    

    【讨论】:

      【解决方案4】:

      我设法通过手动将参数传递给我的 jsx 对象来解决这个问题。我不确定这是否是正确的测试方法,但它现在有效。

      <LoginView model={model} params={params} />
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-26
        • 2018-03-01
        • 2019-03-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多