反应-酶测试-模拟变化返回未定义

时间:2018-09-26 07:26:42

标签: reactjs testing enzyme

我是React Enzyme测试的新手。

我想模拟输入/更改动作。

第二次测试失败,尽管找到了输入'#num1':

Expected value to equal: "23"
Received: "undefined"

我尝试使用'text()'代替'value',然后返回“”。

此外,我编写了一个测试,用于查找按钮文本并传递返回值'+'。

当我删除两个输入之一并找到“输入”时,它也会返回“未定义”。

App.js:

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

class App extends React.Component{
        constructor(){
            super();
            this.state = {
                number1: 0,
                number2: 0,
                result: 0
            }
        }

        render(){
            return(
            <div>
                <div>
                    <label>Number 1</label>
                    <input id="num1" onInput={this.rememberNumber1.bind(this)} />
                    <br/><br/>
                    <label>Number 2</label>
                    <input id="num2" onInput={this.rememberNumber2.bind(this)} />
                </div>
                <div>
                    <h1>{this.state.number1}+{this.state.number2}={this.state.result}</h1>
                </div>
                <div>
                    <button id="an" onClick={this.sum.bind(this)}>+</button>
                    <button onClick={this.subtract.bind(this)}>-</button>
                    <button onClick={this.multiply.bind(this)}>*</button>
                    <button onClick={this.divide.bind(this)}>:</button>
                </div>
            </div>
            )
        }

        rememberNumber1(e){
            if (e.target.value==""){
                this.setState({
                    number1: 0
                })
            }
            else {
                this.setState({
                    number1: e.target.value
                })
            }
        }

        rememberNumber2(e){
            if (e.target.value==""){
                this.setState({
                    number2: 0
                })
            }
            else {
                this.setState({
                    number2: e.target.value
                })
            }
        }

        sum(e){
            this.setState({
                result: Number(this.state.number1)+Number(this.state.number2)
            })
        }

        subtract(e){
            this.setState({
                result: Number(this.state.number1)-Number(this.state.number2)
            })
        }

        multiply(e){
            this.setState({
                result: Number(this.state.number1)*Number(this.state.number2)
            })
        }

        divide(e){
            this.setState({
                result: Number(this.state.number1)/Number(this.state.number2)
            })
        }
}
export default App;

setupTests.js:

import React from 'react';
import { shallow, mount } from 'enzyme';
import App from './App';

import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';

configure({ adapter: new Adapter() });

it('includes input', () => {
    const app = shallow(<App />);
    expect(app.containsMatchingElement(<input/>)).toEqual(true)
});

it('on input', () => {
    const wrapper = mount(<App />);
    wrapper.find('#num1').simulate('change', {target: {value: 23}})
    expect(wrapper.find('#num1').value).toEqual('23')
});

4 个答案:

答案 0 :(得分:1)

您需要在代码中更改两件事

1.give value prop to the inputs
2.give onChange handler instead of onInput, both work the same way

接下来,在您的测试代码中,您需要从以下道具中访问值:wrapper.find("#num1").props().value

这是测试例:

 it("on input", () => {
  const wrapper = mount(<App />);
  const Num = wrapper.find("#num1");
  Num.simulate("change", { target: { value: 23 } });
  wrapper.update();//update wrapper to reflect the setState as component is updated again after setState
  expect(wrapper.find("#num1").props().value).toEqual(23);
});

组件代码:

    class App extends React.Component {
  constructor() {
    super();
    this.state = {
      number1: 0,
      number2: 0,
      result: 0
    };
  }

  render() {
    return (
      <div>
        <div>
          <label>Number 1</label>
          <input
            id="num1"
            value={this.state.number1}
            onChange={this.rememberNumber1.bind(this)}
          />
          <br />
          <br />
          <label>Number 2</label>
          <input
            id="num2"
            value={this.state.number2}
            onChange={this.rememberNumber2.bind(this)}
          />
        </div>
        <div>
          <h1>
            {this.state.number1}+{this.state.number2}={this.state.result}
          </h1>
        </div>
        <div>
          <button id="an" onClick={this.sum.bind(this)}>
            +
          </button>
          <button onClick={this.subtract.bind(this)}>-</button>
          <button onClick={this.multiply.bind(this)}>*</button>
          <button onClick={this.divide.bind(this)}>:</button>
        </div>
      </div>
    );
  }

  rememberNumber1(e) {
    if (e.target.value == "") {
      this.setState({
        number1: 0
      });
    } else {
      this.setState({
        number1: e.target.value
      });
    }
  }

  rememberNumber2(e) {
    if (e.target.value == "") {
      this.setState({
        number2: 0
      });
    } else {
      this.setState({
        number2: e.target.value
      });
    }
  }

  sum(e) {
    this.setState({
      result: Number(this.state.number1) + Number(this.state.number2)
    });
  }

  subtract(e) {
    this.setState({
      result: Number(this.state.number1) - Number(this.state.number2)
    });
  }

  multiply(e) {
    this.setState({
      result: Number(this.state.number1) * Number(this.state.number2)
    });
  }

  divide(e) {
    this.setState({
      result: Number(this.state.number1) / Number(this.state.number2)
    });
  }
}
export default App;

这是工作沙箱:https://codesandbox.io/s/2pkx1l8mn0

答案 1 :(得分:0)

您要使用的输入字段没有值支持,因此使它们成为不受控制的组件。这些类型的字段无法像这里一样直接获取值

<input value={this.state.number} onInput={some function}></input>

因此测试这些组件很繁琐。您必须创建引用。

constructor(){
   this.num1Ref=React.createRef();
}
<input ref={this.num1Ref} onInput={some function}></input>
somefunction(e){
console.log(this.num1Ref.current.value)
<---code for setState--->
}

在测试文件中,您必须为包装器创建实例,并像这样访问 num1Ref

wrapper.instance().num1Ref.current

最好将值属性保留在输入字段中。 谢谢。

答案 2 :(得分:0)

我也遇到了与undefined一样的期望值的问题,后来通过使用mount而不是shallow的方法解决了这个问题。

答案 3 :(得分:0)

这不是一个优雅或可扩展的解决方案,但它确实有效:

const wrapper = mount(<InputField {...basicProps} />);
const inputElement = wrapper.find("input.inputField__input");
inputElement.simulate("change", { target: { value: "1" } });

const updatedInputElement = wrapper.find("input.inputField__input");

expect(updatedInputElement.props().value).toBe("1"); // true

或者类似地:

const wrapper = mount(<InputField {...basicProps} />);
let inputElement = wrapper.find("input.inputField__input");
inputElement.simulate("change", { target: { value: "1" } });

inputElement = wrapper.find("input.inputField__input");

expect(inputElement.props().value).toBe("1"); //true

...正在有效地执行我希望update()方法对单个元素所做的事情。