首页 > 解决方案 > 如何使用 Jest/Enzyme 在功能性 React 组件中测试 lambda 函数?

问题描述

我正在尝试创建一个下拉选项卡,但是我还没有接近添加任何功能,因为我正在尝试执行这种 TDD 样式并且我什至无法测试组件内部的功能是否在按钮的点击事件。笑话日志告诉我,我试图引用的对象不是函数。

我试图创建我正在测试的组件的一个实例,并将其作为参数提供给使用“toBeCalled”函数作为匹配器的“expect”函数,但这不起作用。

组件本身:

import React from "react";
import headerImg from "./headerImg.png";

function PullDown() {
  const displayUPC = () => {};

  return <button onClick={displayUPC} />;
}
export default PullDown;

组件的测试:

import React from "react";
import ReactDOM from "react-dom";
import { shallow, mount, configure, instance } from "enzyme";
import Adapter from "enzyme-adapter-react-16";
import PullDown from "./PullDown";
import enzyme from "enzyme";

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

describe("Pulldown tab", () => {
  let wrapperPulldown;
  beforeEach(() => {
    wrapperPulldown = shallow(<PullDown />);
  });

  it("should render", () => {
    expect(wrapperPulldown.find("button")).toHaveLength(1);
  });

  it("should be clickable", () => {
    wrapperPulldown.find("button").simulate("click");
    expect(wrapperPulldown.displayUPC()).toBeCalled();
  });
});

我预计测试会失败,但确实如此,但是当我将函数添加到组件并添加 onClick 并将函数附加到按钮时,测试仍然失败。这让我觉得我还没有完成正确测试。

标签: javascriptreactjsnpmjestjsenzyme

解决方案


如上所述,原因是该函数不存在,ReactWrapper因为这只是渲染输出周围的一个实例。此外,您不能像在基于常规类的组件中那样检查函数调用,因为它不是类的属性,例如Pulldown.displayUPC.

但是,有几种不同的方法可以测试类似的功能:

如果可能的话,让组件没有隐藏的依赖,并通过 props 传递函数引用。但是,如果您的所有组件都正常工作,这并不总是可行的。

// PullDown.js
function PullDown({displayUPC}) {
  return <button onClick={displayUPC} />;
}
export default PullDown;

// PullDown.spec.js
describe("Pulldown tab", () => {
  let wrapperPulldown;
  let displayUPC;

  beforeEach(() => {
    displayUPC = jest.fn();
  });

  // ... some tests

  it("should be clickable", () => {
    wrapperPulldown = shallow(<PullDown displayUPC={displayUPC} />);
    wrapperPulldown.find("button").simulate("click");
    expect(displayUPC).toBeCalled();
  });
});

如果您没有通过 props 传递函数引用的奢侈,实现此目的的另一种方法是在组件外部定义函数。

// PullDown.js
export const displayUPC = () => {};
function PullDown() {
  return <button onClick={displayUPC} />;
}
export default PullDown;

// PullDown.spec.js
import * as pullDownModule from './PullDown.js';
describe("Pulldown tab", () => {
  let wrapperPulldown;

  beforeEach(() => {
    jest.spyOn(pullDownModule, 'displayUPC');
    wrapperPulldown = shallow(<PullDown />);
  });

  // ... some tests

  it("should be clickable", () => {
    wrapperPulldown.find("button").simulate("click");
    expect(pullDownModule.displayUPC).toBeCalled();
  });
});

推荐阅读