gpt4 book ai didi

reactjs - 如何测试与 Ant Design 的 Popover 内容的交互?

转载 作者:行者123 更新时间:2023-12-03 19:01:40 24 4
gpt4 key购买 nike

我有一个包装了 Ant Design Popover 的 React 组件。该组件在动态生成的内容中获取由用户交互(比如点击)调用的回调。与此类似的东西:

const { Popover, Button } = antd;
const PopoverExtended = ({ onWhatever, children }) => {
const handleClick = (event) => {
if (event.target.className === 'some-class') {
onWhatever(event.target.dataset.value);
}
};
const dynamic = () => '<span class="some-class" data-value="42">Click this text</span>';
const content = () => {
return (
<div>
<p>Some HTML</p>
<div dangerouslySetInnerHTML={{ __html: dynamic() }} onClick={handleClick}></div>
</div>
);
};
return (
<Popover content={content()} placement="right" trigger="click">
{children}
</Popover>
);
};

ReactDOM.render(
<PopoverExtended onWhatever={(x) => console.log(x)}>
<Button>Click me</Button>
</PopoverExtended>,
document.getElementById('root')
);
<link href="https://cdnjs.cloudflare.com/ajax/libs/antd/3.26.20/antd.css" rel="stylesheet"/>

<div id="root" style="margin: 2em 0 0 2em"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment-with-locales.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/antd/3.26.20/antd-with-locales.js" crossorigin="anonymous"></script>

一切都按预期工作,但使用 Jest 和 Enzyme 我试图测试 onWhatever正在调用回调,但到目前为止,我无法将动态内容定位为 ShallowWrapper 或 ReactWrapper。我试过了:
describe(`<PopoverExtended /> interaction`, () => {
const mockChildren = <Button>Mock me</Button>;
const mockCallback = jest.fn();
const wrapper = mount(<PopoverExtended onWhatever={mockCallback}>{mockChildren}</PopoverExtended>);

// Try 1
const trigger = wrapper.find('.some-class[data-value="42"]'); // Nothing found.

// Try 2
const content = mount(<>{wrapper.find(Popover).prop('content')}</>);
console.log(content.html()); // Is apparently the correct Popover content HTML
const trigger = wrapper.find('.some-class[data-value="42"]'); // Nothing found.

// Try 3
const content = mount(<>{wrapper.find(Popover).prop('content')}</>);
const rendered = content.render();
const trigger = wrapper.find('.some-class[data-value="42"]'); // Node found, but
// it's a CheerioWrapper, so I cannot call trigger.simulate('click');
});
关于如何正确测试回调被调用的任何想法?

最佳答案

Enzyme 看不到动态内容,因此您无法模拟点击动态内容中的元素。您可以通过执行 console.log(wrapper.debug()) 来验证这一点这将向您展示 Enzyme 看到的内容。尝试后:

const mockCallback = jest.fn();
const wrapper = mount(<PopoverExtended onWhatever={mockCallback}>{<Button>Mock me</Button>}</PopoverExtended>);

const trigger = wrapper.find("button");
trigger.simulate("click");
enzyme 只到托管 div :
...
<Content trigger={{...}} prefixCls="ant-popover" id={[undefined]} overlay={{...}}>
<div className="ant-popover-inner" id={[undefined]} role="tooltip">
<div>
<div className="ant-popover-inner-content">
<div>
<p>
Some HTML
</p>
<div dangerouslySetInnerHTML={{...}} onClick={[Function: handleClick]} />
</div>
</div>
</div>
</div>
</Content>
...
现在调用 wrapper.html()实际上返回了包括动态内容在内的完整 DOM,但正如你提到的,这对于我们的案例来说毫无用处。为了保护 Enzyme,动态内容使用 html 风格而不是 JSX( class 而不是 className),这使得包装更加困难。
有了这个,我不明白为什么需要在测试场景中包含动态内容。只需模拟 click在主机上 div .事实上,我认为这是正确的做法,因为您在主机 div 上定义了事件处理程序。而不是在动态内容中:
it(`<PopoverExtended /> interaction`, () => {
const mockCallback = jest.fn();
const wrapper = mount(<PopoverExtended onWhatever={mockCallback}>{<Button>Mock me</Button>}</PopoverExtended>);
const mockEvent = {
type: "click",
target: {
dataset: { value: 42 },
className: "some-class"
}
};

const trigger = wrapper.find("button");
trigger.simulate("click");

const hostDiv = wrapper.find("div.trigger-wrapper");
hostDiv.simulate("click", mockEvent);

expect(mockCallback.mock.calls.length).toBe(1);
expect(mockCallback.mock.calls[0][0]).toBe(42);
});
选项 2
有趣的是, react 测试库包含您的动态内容没有问题,因此您可能想要使用它而不是 Enzyme:
import React from "react";
import { render, fireEvent, screen } from '@testing-library/react'
import { Button } from "antd";

import PopoverExtended from "./PopOverExtended";

it(`<PopoverExtended /> interaction`, async () => {
const mockCallback = jest.fn();

render(<PopoverExtended onWhatever={mockCallback}>{<Button>Mock me</Button>}</PopoverExtended>);

fireEvent.click(screen.getByText('Mock me'))
fireEvent.click(screen.getByText('Click this text'))

expect(mockCallback.mock.calls.length).toBe(1);
expect(mockCallback.mock.calls[0][0]).toBe("42");
});
对此的论据是 dataset由动态内容定义,因此您必须在测试中考虑它。

关于reactjs - 如何测试与 Ant Design 的 Popover 内容的交互?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64597504/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com