javascript - 开 Jest/ enzyme 测试 : this. props.showOverlay 不是函数

标签 javascript reactjs unit-testing jestjs enzyme

我有一个模拟点击的小测试(希望通过测试做更多的事情,但这就是我到目前为止所陷入的困境):

import React from 'react';
import Enzyme, { mount } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import HamburgerIcon from './HamburgerIcon';

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

test('hamburger icon changes class and state on click', () => {
  const wrapper = mount(<HamburgerIcon />);
  const hamburgerIcon = wrapper.find('div#mobile-nav');

  hamburgerIcon.simulate('click');
});

运行此测试时,我收到错误:

TypeError: this.props.showOverlay is not a function

经过一些阅读后,我意识到这不起作用,因为模拟点击调用的函数比正在测试的组件 (HamburgerIcon) 高两级。

当我第一次尝试运行它时,我使用的是 Enzyme 的 shallow,此后我将其更改为 mount,认为这将使测试能够访问 >showOverlay 函数,但我错了。

然后我读到这可能是 mock function 的一个很好的用例。 ,我尝试开始实现这个:

...

const showOverlay = jest.fn();
// how to set this.props.ShowOverlay to the const above??

test('has div with class .closed', () => {
  const wrapper = mount(<HamburgerIcon />);
  const hamburgerIcon = wrapper.find('div#mobile-nav');

  hamburgerIcon.simulate('click');
});

这就是我有点迷失的地方——我不确定模拟函数是否是正确的方向,而且我也不确定设置模拟函数的语法将如何工作。

最佳答案

继续shallow如果您只是对单个组件进行单元测试。如果此组件是嵌套的并且您正在针对子节点进行测试,那么您将 mount父级。

也就是说,您使用模拟函数的方向是正确的。只需将其传递到组件中,如下所示:

<HamburgerIcon showOverlay={showOverlay} />

例如:

const showOverlay = jest.fn();

test('shows an overlay', () => {
  const wrapper = mount(<HamburgerIcon showOverlay={showOverlay} />);
  const hamburgerIcon = wrapper.find('div#mobile-nav');

  hamburgerIcon.simulate('click');
  expect(showOverlay).toHaveBeenCalled();
});

如果你有多个 props,那么我喜欢做一些更具声明性的事情:

// define props here if you want an easy way check if they've been 
// called (since we're defining at the top-level, all tests have access
// to this function)
const showOverlay = jest.fn();

// then include them in an "initialProps" object (you can also just define
// them within this object as well, but you'll have to use 
// "initialProps.nameOfFunction" to check if they're called -- kind of 
// repetitive if you have a lot of props that you're checking against)
const initialProps = {
  showOverlay,
  someOtherFunction: jest.fn()
}

// use the spread syntax to pass all the props in the "initialProps" object
// to the component
test('shows an overlay', () => {
  const wrapper = mount(<HamburgerIcon { ...initialProps } />);
  const hamburgerIcon = wrapper.find('div#mobile-nav');

  hamburgerIcon.simulate('click');

  expect(showOverlay).toHaveBeenCalled(); // here we can just use the mock function name
  expect(initialProps.someOtherFunction).toHaveBeenCalledTimes(0); // here we'll have to use "initialProps.property" because it has been scoped to the object
});

关于javascript - 开 Jest/ enzyme 测试 : this. props.showOverlay 不是函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56403596/

相关文章:

javascript - 如果 JSON 字段为空,如何将空数组字段附加到 JSON 中?

javascript - 客户应该如何与服务交互?

javascript - 增加 D3 环图中环之间的空间

c# - 测试通用类

javascript - WordPress 自定义帖子类型的“智能”历史后退按钮

reactjs - 如何使类对象在 MobX 中可观察?

javascript - 使用按钮打开对话框以获取一些用户输入

javascript - 将两个下拉过滤器连接到一个搜索按钮

python - 在 Python 中模拟 ImportError

java - 使用mockito测试带有条件循环的void方法