javascript - 在 Enzyme 中,如何从函数组件的 props 中获取函数?
问题描述
我正在使用 Jest 和 Enzyme 为我的反应项目编写单元测试。
如下图,我通过props传递了一个名为updateUser
待测组件的函数。EditCard
describe('The EditCard screen', () => {
let wrapper;
beforeEach(() => {
const defaultProps: Partial<EditCardProps> = {
toggleEditing: jest.fn(),
user: mockUsers[0],
updateUser: jest.fn(), // passes this function to the "EditCard" component via props
showSnackbar: jest.fn(),
};
wrapper = shallow(<EditCard {...(defaultProps as EditCardProps)} />);
});
然后我想测试模拟点击按钮后调用了多少次。
it('should match the snapshot when the "Name" textfield is not filled and the "submit" button is clicked', () => {
wrapper.find('#Name').simulate('change', { target: { value: null } });
wrapper.find('#submit').simulate('click');
// Try to get the "updateUser" function from the props, but get "undefined".
expect(wrapper.prop('updateUser')).toHaveBeenCalledTimes(0);
});
但我得到了如下所示的错误:
Matcher error: received value must be a mock or spy function
Received has value: undefined
24 | wrapper.find('#Name').simulate('change', { target: { value: null } });
25 | wrapper.find('#submit').simulate('click');
> 26 | expect(wrapper.prop('updateUser')).toHaveBeenCalledTimes(0);
有人能告诉我我哪里做错了吗?为什么我无法从道具中获取功能undefined
并被退回?
提前致谢!
解决方案
对您的代码进行一些调整应该可以使其正常工作...
import * as React from "react";
import { mount, ReactWrapper } from "enzyme";
import EditCard from "../path/to/EditCard";
/*
I'd recommend defining jest fns here to make them easier to reference anywhere
within the tests below; otherwise, it'll have to referenced via
'defaultProps.updateUser', 'defaultProps.showSnackbar', ...etc.
Using 'const' here allows us to define these variables within the
module's closure -- in short, only accessible within these tests and NOT
globally accessible (from other file tests).
*/
const showSnackbar = jest.fn();
const toggleEditing = jest.fn();
const updateUser = jest.fn();
/*
if the EditCard component is properly typed, then you shouldn't need to
add types to this 'defaultProps' object
*/
const defaultProps = {
showSnackbar,
toggleEditing,
updateUser,
user: mockUsers[0]
};
describe('The EditCard screen', () => {
let wrapper: ReactWrapper;
beforeEach(() => {
/*
I'd recommend mount over shallow because child components can be
deeply nested and require multiple .dive calls; however, if
you know the child components of "EditCard" are just simple JSX elements,
then shallow will be fine
*/
wrapper = mount(<EditCard {...defaultProps} />);
});
it("should not call 'updateUser' when the form is submitted with an empty '#Name' field", () => {
/*
I'm not sure what simulating "null" does for this input, but assuming this
input is required you should at least pass a string value -- assuming
"#Name" input is of type 'text' | 'password' | 'email' => string and
not a number. On a related note, if it's required, then simply remove this
code as it doesn't do much for the test.
*/
// wrapper.find('#Name').simulate('change', { target: { value: "" } });
/*
I'm assuming this then simulates a form submit. Unfortunately,
pressing the submit button won't work. Instead you'll have to
simulate a form submit. This is a limitation of Enzyme and last I
checked hasn't been/can't be fixed.
*/
wrapper.find('form').simulate('submit');
/*
it should then NOT call the jest.fn() "updateUser" when submitted since
'#Name' is empty. Notice that we're referencing 'updateUser' -- the jest fn
defined above -- and not the wrapper.prop fn.
*/
expect(updateUser).not.toHaveBeenCalled();
});
// include other tests...
});
这是一个工作示例(单击Tests
选项卡以运行测试):
推荐阅读
- angular - 如何修复量角器中的**“值”的值超出范围**错误?
- javascript - VueJS Datepicker:如何动态禁用日期?
- html - 有没有办法在右下角和左下角对齐文本?
- javascript - “用户服务列表”页面新增类别的外观
- c# - 从表中过滤具有逗号和管道分隔值的列
- ruby-on-rails - Rails 5.2 中的表单提交问题
- jquery - 使用 ajax 和 java 脚本生成链接的动态下拉列表
- cmake - CMakeLists 使用变量来定义源/包含位置
- drupal - 安装问题我的网址在 Drupal 8 安装中不起作用
- mysql - 使用 ONLY_FULL_GROUP_BY ON 的 Symfony 查询