如何使用 Jest/Enzyme 在功能性 React 组件中测试 lambda 函数?

Posted

技术标签:

【中文标题】如何使用 Jest/Enzyme 在功能性 React 组件中测试 lambda 函数?【英文标题】:How to test lambda functions in a functional React Component using Jest/Enzyme? 【发布时间】:2019-07-03 20:26:17 【问题描述】:

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

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

组件本身:

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 并将函数附加到按钮时,测试仍然失败。这让我觉得我没有t 测试正确。

【问题讨论】:

displayUpc 不是浅包装的属性(这里也不需要浅渲染)。就此而言,它不是PullDown 组件的属性;它是函数中的局部变量。您的组件毫无意义,因此您可以为它编写真正的合理测试。请注意,您预期的测试失败可能不是is not a function 这就是为什么重要的是“发号施令”(预测测试结果)并将实际结果与您的预期进行比较。您可能希望看到“预期的 已被调用,但它没有被调用。”,而不是“wrapperPulldown.displayUPC 不是函数”,尽管 displayUpc 不是模拟的事实无论如何都不太可能。 你是对的!我对这一切都很陌生,如果不是为了测试组件的功能,我不确定我是否理解浅渲染的意义?您能给我一些关于如何正确测试组件中按钮功能的见解吗? 你不能测试它的功能,因为它没有任何功能。一旦它更新 DOM 或与协作者交互,您就可以对其进行测试,但目前它并没有任何事情。 那么你想实现什么功能?你实际上并没有提到这一点。回调会做什么?您不想测试回调是否被调用,因为这是一个内部实现细节(并且不能,因为它在函数外部无法访问),那么 行为 是什么? 【参考方案1】:

如上所述,原因是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();
  );
);

【讨论】:

以上是关于如何使用 Jest/Enzyme 在功能性 React 组件中测试 lambda 函数?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Jest/Enzyme 测试去抖功能?

如何使用 JEST、Enzyme 在 React 中测试自定义钩子?

使用 Jest / Enzyme 在 React 中的功能组件内部测试方法

Jest/Enzyme 单元测试:如何将存储传递给使用 redux 4 和 react-redux 6 连接功能的浅层组件

使用 Jest/Enzyme 在 React 功能组件中测试封闭组件

如何使用 jest/enzyme 测试 useEffect 与 useDispatch 挂钩?