【问题标题】:Testing onClick event on react component using Jasmine使用 Jasmine 在反应组件上测试 onClick 事件
【发布时间】:2016-07-12 22:55:57
【问题描述】:

我有一个 React 组件,它的按钮的 onClick 事件绑定到作为属性从父组件传递的函数,例如<Counter counter=0 incrementCounter={incrementFunction} decrementCounter={decrementFunction} />.

我是单元测试 React 组件的新手,所以我试图检查在单击递增/递减按钮时是否调用了该函数。为此,我使用了 Jasmine 的 spyOn 方法,但它似乎永远无法捕捉到被调用的函数。

如果我在我正在使用的函数(例如let incrementCounter = () => { console.log("increment!"); };)中输出一个console.log,那么当我执行TestUtils.Simulate.click(incrementButton); 时,我可以知道该函数正在被调用,但是测试仍然不会通过。我错过了什么?

Counter.js

import React, { Component, PropTypes } from "react";

class Counter extends Component {

  constructor(props) {
    super(props);
  }

  render() {
    const { incrementCounter, decrementCounter, counter } = this.props;
    return (

        <div>
          <h1>Counter</h1>
          <p>
            <b>Counter: {counter} times</b>
            {" "}
            <button onClick={incrementCounter}>+</button>
            {" "}
            <button onClick={decrementCounter}>-</button>
          </p>
        </div>

    );
  }
}

Counter.propTypes = {
  incrementCounter: PropTypes.func.isRequired,
  decrementCounter: PropTypes.func.isRequired,
  counter: PropTypes.number.isRequired
};

export default Counter;

Counter.test.js

import React from "react";
import TestUtils from "react/lib/ReactTestUtils";
import Counter from "./Counter"

describe("Counter", function () {

  let renderedComponent = {};
  let heading = {};
  let decrementButton = {};
  let incrementButton = {};
  let incrementCounter = () => {};
  let decrementCounter = () => {};
  let counter = 0;

  beforeEach(function(){

    renderedComponent = TestUtils.renderIntoDocument(
        <Counter incrementCounter={incrementCounter} decrementCounter={decrementCounter} counter={counter} />
    );

    heading = TestUtils.findRenderedDOMComponentWithTag(renderedComponent, "h1");

    let buttons = TestUtils.scryRenderedDOMComponentsWithTag(renderedComponent, "button");

    decrementButton = buttons[1];
    incrementButton = buttons[0];

    this.incrementCounter = incrementCounter;

  });

  it("renders without problems", function () {

    expect(TestUtils.isDOMComponent(heading)).toBe(true);
    expect(heading.innerText).toMatch(/Counter/g);

    expect(TestUtils.isDOMComponent(decrementButton)).toBe(true);
    expect(decrementButton.innerText).toMatch(/-/g);

    expect(TestUtils.isDOMComponent(incrementButton)).toBe(true);
    expect(incrementButton.innerText).toMatch(/\+/g);

  });

  it("fires the increment function", function() {

    spyOn(this, "incrementCounter");
    TestUtils.Simulate.click(incrementButton);
    expect(this.incrementCounter).toHaveBeenCalled(); // Error: fuction doesn't get called

  });

});

【问题讨论】:

    标签: unit-testing reactjs jasmine


    【解决方案1】:

    我不太清楚 Jasmine 是如何用 spyOn 实际包装函数的,但请尝试在 beforeEach 的顶部设置 this.incrementCounter = incrementCounter 并直接在组件中使用它:

    beforeEach(function(){
      let that = this;
      this.incrementCounter = incrementCounter;
      renderedComponent = TestUtils.renderIntoDocument(
        <Counter incrementCounter={that.incrementCounter} decrementCounter={decrementCounter} counter={counter} />
    );
    

    如果由于that/this 的故障仍然不起作用,则从一开始就将incrementCounter 声明为间谍:

    let incrementCounter = jasmine.createSpy('incrementCounter')
    

    并在&lt;Counter /&gt; 和其余测试中使用它。

    【讨论】:

    • let incrementCounter = jasmine.createSpy('incrementCounter'); 工作!
    猜你喜欢
    • 2015-03-31
    • 2017-08-05
    • 2018-07-18
    • 2016-07-25
    • 1970-01-01
    • 2013-05-29
    • 1970-01-01
    • 2019-12-25
    • 1970-01-01
    相关资源
    最近更新 更多