有没有办法模拟 SVGTextElement 以便能够使用 Jest 测试函数,该函数使用 getBBox() 来测量文本?

Kre*_*eha 5 javascript svg typescript jestjs

在决定应该使用什么字体大小之前,我编写了简单的函数来测量文本。

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,
  };
};
Run Code Online (Sandbox Code Playgroud)

它非常简单,而且效果很好,但我在为此编写单元测试时遇到问题。问题是,在浏览器中工作时,它在测试期间不起作用并引发错误

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({});
  });
});
Run Code Online (Sandbox Code Playgroud)

Mic*_*sky 1

getBBox只能用于类型SVGGraphicsElement

在下面创建一个<svg>元素body,然后在<text>下面添加一个元素svg

然后你可以调用getBBox().widthtext元素