问题描述
我有以下组件:
import React,{ useEffect,useRef,useState } from 'react';
import PropTypes from 'prop-types';
// Import all icon names
import { ICONS } from 'assets/icons';
// Styles
import css from './index.module.css';
// Empty SVG to fall back to until targeted icon is loaded
const FALLBACK = () => <svg aria-label="" data-testid="icon-fallback" viewBox="0 0 20 20" />;
// Default acceptable icon weights
const WEIGHTS = ['light','heavy'];
/**
* SVG Icons
*
* @p@R_404_6460@m {string} ariaLabel aria-label for the icon. Used primarily when the icon is not accompanied by descriptive text.
* @p@R_404_6460@m {bool} ariaHidden Should we hide the icon from assistive devices? Used when icon is not accompanied by descriptive text.
* @p@R_404_6460@m {string} name Name of the icon to load. Must match a name in the ICONS array above.
* @p@R_404_6460@m {weight} weight Icon weight. Can be light or heavy.
* @returns {Node}
*/
const Icon = ({
ariaLabel,ariaHidden,name,weight,}) => {
// When !isMounted don’t update the icon.
const isMounted = useRef(true);
const [icon,setIcon] = useState(null);
useEffect(() => {
if (
isMounted.current
&& ICONS.includes(name)
&& WEIGHTS.includes(weight)
) {
/* Use dynamic import to get corresponding icon as a module */
import(`assets/icons/${weight}/${name}.svg`)
.then(module => {
setIcon(module);
})
.catch(() => {
console.error(`Icon with name: ${name} not found!`);
setIcon(null);
});
}
},[name,weight]);
useEffect(() => {
return () => { isMounted.current = false; };
},[]);
const Component = icon ? icon.default : icon;
return (
<i
aria-hidden={ariaHidden}
className={css.Icon}
>
{
icon ? (
<Component aria-labelledby={ariaLabel} data-testid="icon-module" />
) : (
<FALLBACK />
)
}
</i>
);
};
Icon.defaultProps = {
ariaLabel: '',ariaHidden: false,name: 'picture',weight: 'light',};
Icon.propTypes = {
/**
* If the icon is being displayed without accompanying text (like in a link or button),use `ariaLabel` to add descriptive text for screen readers
*/
ariaLabel: PropTypes.string,/**
* If the icon is accompanied by descriptive text (like in a link or button) use `ariaHidden` to hide the icon from screen readers.
*/
ariaHidden: PropTypes.bool,/**
* The name of the icon to use.
*/
name: PropTypes.oneOf(ICONS),/**
* Size of the icon
*/
weight: PropTypes.oneOf(WEIGHTS),};
export { Icon };
我试图用测试覆盖动态导入的 catch()
部分,但我似乎无法让测试达到捕获,即使我传递了错误的图标名称。
我的测试:
import React from 'react';
import { render,waitFor } from '@testing-library/react';
import {Icon} from '.';
test.only('loads fallback icon',async () => {
const { getByTestId } = render(<Icon name="bloop" />);
const iconModule = await waitFor(() => getByTestId('icon-fallback'));
expect(iconModule).toBeInTheDocument();
});
是什么?
编辑
这是一个 CodesandBox 复制来说明这个问题:https://codesandbox.io/s/testing-libraryreact-dynamic-import-p7cl9?file=/src/index.js
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)