用 Enzyme/Jest 模拟点击测试不调用 Sinon Spy

Simulate Click Test with Enzyme/ Jest Not Calling Sinon Spy

我有一个正在构建的 React 应用程序,我正在使用 Enzyme、Jest 和 Sinon 对其进行测试。我在应用程序测试的其他组件上使用了 sinon.spy() 来验证是否调用了 onClick 方法;但是,它不适用于此特定组件。我也知道当我在浏览器中 运行 应用程序时,onClick 确实有效。我的测试结果失败了 - "Expected: true; Received: false"。

此组件创建一个重定向到 URL 的按钮列表。该组件的代码如下:

import React from "react";
import List from "@material-ui/core/List";
import ListSubheader from "@material-ui/core/ListSubheader";
import {
  withStyles
} from "@material-ui/core/styles";
import Button from "@material-ui/core/Button";
import Paper from "@material-ui/core/Paper";
import styles from "./styles";

class ChannelList extends React.PureComponent {
    handleClick = channelURL => async event => {
      const {
        history,
        enterChannel
      } = this.props;
      await enterChannel(channelURL);
      history.push(`/chat/${channelURL}`);
    };

    render() {
      const {
        classes: {
          channelListContainer,
          channelButtonList,
          channelButton
        },
        channels
      } = this.props;
      return ( <
        div className = {
          channelListContainer
        } >
        <
        Paper >
        <
        List className = {
          channelButtonList
        }
        subheader = { < ListSubheader color = "primary" > Channels < /ListSubheader>} >
          {
            channels.map((channel, index) => {
              const {
                name,
                url
              } = channel;
              return ( 
              <div key = {
                  name + index.toString()
                } >
                <Button data - testid = {
                  `${name}${index.toString()}`
                }
                onClick = {
                  this.handleClick(url)
                }
                className = {
                  channelButton
                } >
                { name } 
                </Button> 
              </div>
              );
            })
          } 
          </List> 
          </Paper> 
          </div>
        );
      }
    }

    export default withStyles(styles)(ChannelList);

而我的测试代码如下:

import React from "react";
import {
  shallow
} from "enzyme";
import sinon from "sinon";
import ChannelList from "../ChannelList";
import List from "@material-ui/core/List";
import Button from "@material-ui/core/Button";

describe("<ChannelList />", () => {
      const props = {
        channels: [{
            name: "test-channel1",
            url: "www.test1.com"
          },
          {
            name: "test-channel2",
            url: "www.test2.com"
          },
          {
            name: "test-channel3",
            url: "www.test3.com"
          }
        ]
      };

      let wrapper;

      beforeEach(() => {
          wrapper = shallow( <ChannelList { ...props}/>).dive();
      });

        test("handleClick is called when clicking on a list item", () => {
          const spy = sinon.spy(wrapper.instance(), "handleClick");
          const button1 = wrapper.find({
            "data-testid": "test-channel10"
          }).dive();
          expect(button1).toHaveLength(1);
          console.log(button1.debug());
          button1.simulate("click");
          expect(spy.called).toBe(true);
        });
});

问题是:你的 Button 元素有这个属性:

onClick = {
      this.handleClick(url)
}

它没有将 onClick 回调设置为 this.handleClick(),而是在渲染期间立即调用 this.handleClick(),然后将 onClick 属性设置为 return 函数的值。因为这发生在您创建间谍之前,所以测试失败。

你可能应该

onClick = {
   () => this.handleClick(url)
}

...或类似的。