【问题标题】:Simulate Click Test with Enzyme/ Jest Not Calling Sinon Spy用 Enzyme/Jest 模拟 Click Test 不调用 Sinon Spy
【发布时间】:2019-06-22 20:59:57
【问题描述】:

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

此组件创建一个重定向到 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);
        });
});

【问题讨论】:

    标签: javascript reactjs jestjs enzyme sinon


    【解决方案1】:

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

    onClick = {
          this.handleClick(url)
    }
    

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

    你应该这样做

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

    ...或类似的。

    【讨论】:

    • 成功了。感谢您查看我的问题!这引发了一个次要问题。我对 React 比较陌生,但是在渲染中声明函数是否会对性能产生影响?我假设在这种情况下它是最小的,因为它本质上只是一个调用另一个函数的函数。再次感谢!
    • 这并不理想,但从代码的角度来看,有时最好接受打击(特别是如果您不经常重新渲染,或者只显示少量实例)。您可以通过将频道按钮分解为一个单独的组件来绕过它,然后它可以有一个名为 handleClick 的实例方法,它可以访问this.props.channel 或其他任何东西。在这种情况下,我会说这不值得。
    猜你喜欢
    • 2019-08-28
    • 2019-01-29
    • 2016-10-11
    • 2017-12-18
    • 2019-06-09
    • 2016-07-09
    • 2018-03-28
    • 2019-10-27
    • 2020-11-17
    相关资源
    最近更新 更多