我有一个模拟点击的小型测试(希望对测试做更多的工作,但这是我目前为止遇到的问题):
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不是函数
经过一番阅读后,我意识到这是行不通的,因为模拟的点击会调用一个比正在测试的组件(HamburgerIcon
高两级的函数。
当我第一次尝试运行此程序时,我正在使用酶的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');
});
这是我迷失的地方-我不确定模拟函数在这里是否是正确的方向,也不确定设置模拟函数的语法将如何工作。
答案 0 :(得分:1)
如果您只是对单个组件进行单元测试,请继续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();
});
如果您有多个道具,那么我想做些更具说明性的事情:
// 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
});