我是单元测试用例的新手,我的项目使用的是带有React的typescript。我希望在为我的组件之一编写以下代码的测试用例时得到一些帮助。我一直在尝试编写一个测试用例来满足这里的getLogo和setupRegistry两个函数。无法找出正确的方法来完成这一操作-
import {
getMediaToken,
isManifestRegistryItem,
MediaRegistryHelper,
RegistryItem,
SupportedRegistryMedia,
SvgUtils,
} from 'common';
import React, {
FunctionComponent,
useEffect,
useState,
useContext,
} from 'react';
import { Observable, of } from 'rxjs';
import { filter, map } from 'rxjs/operators';
import { downloadMedia, loadMediaRegistry } from '../media-registry';
import { LogoAssetContext } from '../media-context';
export interface RBCLogoProperties {
token: string;
srLabel: string;
}
type RBCLogoType = RBCLogoProperties & React.HTMLAttributes<HTMLLabelElement>;
export const RCLogo: FunctionComponent<RBCLogoType> = (props: RBCLogoType) => {
const { token, srLabel } = props;
const LOGOASSETREGISTRY = useContext(LogoAssetContext);
useEffect(() => {
setupRegistry(
LOGOASSETREGISTRY as Array<RegistryItem<SupportedRegistryMedia>>,
);
});
// Media Helper Instance to access the methods defined in media helper
const mediaHelperInstance = new MediaRegistryHelper();
// State to set the svg to html to show the logo
const [svg, setSVG] = useState<string>();
//Set up the registry for logo assets
const setupRegistry = (
registryConfig: Array<RegistryItem<SupportedRegistryMedia>>,
) => {
let config: Array<RegistryItem<SupportedRegistryMedia>> = [];
if (registryConfig && registryConfig.length > 0) {
const items = registryConfig;
config = [...config, ...items];
}
loadMediaRegistry?.('logo', config).subscribe(() => getLogo());
};
const getLogo = () => {
if (token) {
const logo = getMediaToken(token);
const registryItem = mediaHelperInstance?.getRegistryMediaItem(
'logo',
logo.scope || 'default',
);
let item$: Observable<RegistryItem<SupportedRegistryMedia> | undefined> =
of(registryItem);
if (isManifestRegistryItem(registryItem)) {
item$ = registryItem.data.pipe(
filter((v) => !!v),
map(() => registryItem),
);
}
const downLoadMediaResponse = downloadMedia('logo', logo);
downLoadMediaResponse
? downLoadMediaResponse.subscribe((data: any) => {
const svg = data as SVGElement;
setSVG(svg.outerHTML);
SvgUtils.setSvgAttributes(svg);
SvgUtils.addA11ytoSVG(
svg,
token,
srLabel ? srLabel : ' ',
document,
);
})
: console.log('Download Media Response is undefined for', token);
}
};
return (
<div
aria-label={srLabel}
dangerouslySetInnerHTML={{ __html: svg || '' }}
></div>
);
};
export default RCLogo;
1条答案
按热度按时间5f0d552i1#
关于React组件的单元测试,您通常根据组件测试整个单元,而不能测试
getLogo
和setupRegistry
(我假设这就是您所说的setSubscription
?如果不是,您需要为该函数添加一个代码段)。你不能测试那些特定的函数,因为它们被封装在你的组件中,测试运行者不能访问它们。更重要的是,测试运行者不应该访问它们,因为这会暴露组件的实现细节,测试应该是不可知的。
但是,测试组件内函数的方法有限,但前提是函数在其他地方声明并导入到组件中。然后,您可以使用
spy
来观察被监视的方法是否被调用过,调用的次数是多少。同样,您只能在特定情况下使用它(假设您需要测试组件中的分析事件是否只被分派过一次,即使组件重新呈现等。)因此,如果我为这个组件编写一个单元测试,我将有以下测试用例:
1.组件是否返回预期的svg徽标元素?
1.艾瑞亚的标签正确吗?
我不会测试
getLogo
或任何其他封装的函数,因为您关心的是最终的SVG输出。因此,在测试此组件之前,您需要从所提供的代码示例中获得三件东西。
1.用预期的数据模拟API响应(可以使用Jest nock)
1.将组件 Package 到LogoAssetContext提供程序中,以便组件可以访问它。
1.为部件提供正确的支撑。
还有一个关于how much value the unit test brings的争论,即表示性组件(如徽标)除了显示image/svg之外不做任何事情。
另外,我会尽量避免使用危险的set HTML来呈现SVG。因为它是作为字符串返回的,而且也是从API调用返回的,所以我不相信从其他地方返回的信息会被用来设置内部HTML。如果svg不是真正的svg,它会使您面临XSS攻击。
我会在你的div中使用类似下面的东西。