javascript - Jest : Unit test toHaveBeenCalled() not working

标签 javascript reactjs testing jestjs enzyme

我在 React 中有一个小组件,它在渲染时生成两个随机数,然后要求用户提交这些数字的总和,如果它们正确,则增加他们的分数。

以下代码处理此游戏并在浏览器中按预期运行:

import React, { Component } from 'react';

export const randomNumber = () => {
  var maxNumber = 10;
  var randomNumber = Math.floor((Math.random() * maxNumber) + 1);
  return randomNumber;
}

class Arithmetic extends Component {
  constructor(props) {
    super(props);

    this.state = {
      value: '',
      numbers: {
        x: randomNumber(),
        y: randomNumber()
      },
      score: ''
    }

    this.updateVals = this.updateVals.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.handleChange = this.handleChange.bind(this);
  }

  updateVals() {
    this.setState({
      numbers: {
        x: randomNumber(),
        y: randomNumber()
      },
      score: this.state.score + 1
    });
  }

  componentDidMount() {
    this.setState({
      score: 0
    });
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
    var isCorrect = this.state.numbers.x + this.state.numbers.y == this.state.value ? this.updateVals()  : alert("Try again");
    event.preventDefault();
  }

  render() {
    return (
      <section className="arithmetic">
        <div className="arithmetic__game">
          <div className="row arithmetic__row--details">
            <div className="arithmetic__score">
            Score:&nbsp;&nbsp;{this.state.score}
            </div>
            <div className="arithmetic__timer">
            </div>
          </div>
          <div className="row arithmetic__row--main">
            <div className="arithmetic__examples">
              1 + 1 = 2<br/>
              2 + 1 = 3<br />
            </div> 
            <div className="arithmetic__game-container">
            What is {this.state.numbers.x} + {this.state.numbers.y}?
              <div className="arithmetic__form-container">
                <form onSubmit={this.handleSubmit}>
                  <label>
                    Answer: &nbsp;&nbsp;
                    <input className="input-field" type="text" value={this.state.value} onChange={this.handleChange} />
                  </label>
                  <button className="btn-submit" type="submit" onClick={(e) => (this.handleSubmit) ? this.handleSubmit(e) : null}>Submit</button>
                </form>
              </div>
            </div>
          </div>
        </div>
      </section>
    );
  }
};

但是,当尝试检查是否在正确输入两个数字的总和时调用 updateVals 时,此操作失败。我已经检查过是否在模拟单击“提交”按钮时调用了 handleSubmit,并且它被调用了。我还检查了 valuenumbers 属性的值,看看状态是否已正确更新,它们已经更新了。

但是,当调用 updateVals 时,分数会增加(同样,这会显示在浏览器中)。但是,当我尝试在 Jest 中对此进行模拟时,分数仍保持为 0,就像它初始化时一样。

我的测试如下:

it("passes with correct input", () => {
      const updateVals = jest.fn();
      const handleSubmit = jest.fn();
      Arithmetic.prototype.updateVals = updateVals;
      Arithmetic.prototype.handleSubmit = handleSubmit;
      let wrapper = mount(<Arithmetic />);

      wrapper.find('.input-field').instance().value = wrapper.update().state().numbers.x + wrapper.update().state().numbers.y;
      expect(wrapper.find('.input-field').instance().value).toEqual((wrapper.update().state().numbers.x + wrapper.update().state().numbers.y).toString());
      wrapper.find('.input-field').simulate('change');
      wrapper.find('.btn-submit').simulate('click');
      console.log(wrapper.update().state().numbers.x, wrapper.update().state().numbers.y, wrapper.update().state().value);
      expect(updateVals).toHaveBeenCalled();
    });

在终端中运行测试表明,例如,如果 numbers.x 是 1 并且 numbers.y 是 9 那么 state 中的值键是 '10'。我不确定为什么当我测试 handleSubmit 时,它被调用并且测试通过但 updateVals 没有。

最佳答案

我设法让它工作,我从提交按钮中删除了所有事件,并测试了已经调用 onSubmit 的表单本身,并测试了分数本身是否在状态中更新。

it("passes with correct input", () => {
  const wrapper = shallow(<Arithmetic />);
  const preventDefault = jest.fn();
  const currentScore = wrapper.update().state().score;

  wrapper.find('.input-field').simulate('change', {target: {value: wrapper.update().state().numbers.x + wrapper.update().state().numbers.y}});
  wrapper.find('.main-form').simulate('submit', { preventDefault });
  expect(wrapper.update().state().score).toEqual(currentScore+1);
});

关于javascript - Jest : Unit test toHaveBeenCalled() not working,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50882849/

相关文章:

javascript - 使用 jQuery 删除父 Div 内的 Div 类

java - 在 Java 中创建假 URL

javascript - 无法对过滤后的网格面板进行排序(带 fiddle )

javascript - 如何获取用户在搜索引擎结果页面点击的内容?

javascript - React - JSX 语法问题,以及如何迭代 map 并在换行符上显示项目

javascript - 如何确保使用 useState() Hook 的 React 状态已更新?

java - 在 Appium-java 中寻找用于完整应用程序测试的良好编码格式

javascript - iframe 用于广告加载好还是坏?

testing - 找不到元素 : Trying to verify a disabled button

javascript - 使用 Mocha 进行 Javascript 测试时 assert.equal 和 assert.deepEqual 之间的区别?