javascript - 有没有办法模拟 SVGTextElement 以便能够使用 Jest 测试使用 getBBox() 来测量文本的函数?
问题描述
在决定使用什么字体大小之前,我编写了简单的函数来测量文本。
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
const text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
svg.appendChild(text);
interface HeightAndWidth {
width: number;
height: number;
}
interface MeasureProps {
label: string;
fontFamily: string;
size: number;
fontWeight?: number;
lineHeight?: number;
letterSpacing?: string;
}
export const measureText = ({
label,
fontFamily,
size,
fontWeight = 400,
lineHeight = 1,
letterSpacing = '0',
}: MeasureProps): HeightAndWidth => {
text.setAttribute('font-size', `${size}px`);
text.setAttribute('line-height', `${lineHeight}px`);
text.setAttribute('font-family', fontFamily);
text.setAttribute('font-weight', `${fontWeight}`);
text.setAttribute('letter-spacing', letterSpacing);
text.textContent = label;
document.body.appendChild(svg);
const { width, height } = text.getBBox();
return {
width,
height,
};
};
它非常简单,而且效果很好,但是我在为此编写单元测试时遇到了问题。问题是在浏览器中工作时它在测试期间不起作用并引发错误
text.getBBox 不是函数。
我尝试模拟window.SVGTextElement
,但它不断抛出错误,它的原型缺少 241 个属性。甚至尝试过它的类型,但错误仍然存在,并且缺少getBBox
重复的错误。
有没有办法像这样测试代码?
import { measureText } from '../measure';
interface MockSvgTextElement {
prototype: {
getBBox: () => { height: number; width: number };
};
}
describe('animateNumber', () => {
beforeEach(() => {
window.SVGTextElement = {
prototype: {
getBBox: () => ({
height: 20,
width: 100,
}),
},
} as MockSvgTextElement;
const p = document.createElement('p');
document.body.appendChild(p);
console.log('window.SVGTextElement', window.SVGTextElement);
});
it('should measure text', () => {
const textSize = measureText(
{
label: '12345',
fontFamily: 'Roboto',
size: 20,
}
);
expect(textSize).toEqual({});
});
});
解决方案
getBBox
只能用于SVGGraphicsElement
类型。
在下创建一个<svg>
元素body
,然后附加一个<text>
下svg
。
getBBox().width
然后你可以调用text
元素
推荐阅读
- c# - 具有多个 HttpPost 方法的 Web Api 中的 CORS 问题
- php - PHP 脚本 - 如何在我的脚本中使用 php artisan 命令?
- sql - Redshift:范围连接的 DIST KEY 和 SORT KEY 策略
- angular - Angular Material进度微调器在线
- reactjs - 如何在 React Semantic UI 中使用 List 组件“items”道具?
- c - 我们如何在#define 语句中使用联合和结构
- r - 如何有效地为 stan 数据块指定一个大的预测矩阵
- python - 如何向 HyperlinkedModelSerializer 添加额外数据?
- ios - iOS:UIAlertController 上的 textField 成为当前警报时的第一响应者
- php - wp_query 搜索结果不是预期的