【问题标题】:Mock canvas toDataUrl without adding another lib在不添加其他库的情况下模拟画布 toDataUrl
【发布时间】:2023-02-03 06:36:03
【问题描述】:

我有一个 HTML <canvas> 元素,它使用 onTouchEnd 属性获取画布内容并转换为 dataUrl,但这不受 Jest 支持。

大多数文章建议添加 jest-canvas-mock 库来模拟所有 HTMLCanvasElement 的东西。但这似乎有些矫枉过正,因为我只需要模拟 toDataURL 方法。所以我想检查如何使用 jest.mock 或 jest.spyOn 模拟 toDataURL() 并返回固定字符串。

为了清楚起见,我需要这个,因为 onChange 函数设置了一个状态值 (useState) 来控制按钮是否启用。

组件.js

export default function MyComponent() {

  const setTouchPosition = e => {
    const canvas = document.getElementById('canvas');

    const rect = canvas.getBoundingClientRect();
    // .. a few lines omitted for readability
  };

  const draw = e => {
    const canvas = document.getElementById('canvas');
    const context = canvas.getContext('2d');
    // .. a few lines omitted for readability
  };


  return (
    <canvas
        onTouchEnd={e => {
              onChange(e.target.toDataURL());
              onTouchMove={e => draw(e)}
              onTouchStart={e => {
                setTouchPosition(e);
              }}
            }}
        />
  );
}

查看.js

export default function MyView() {

  const [data, setData] = useState('');
  const onChange = image => {
    setData(image);
  };

  return (
    <Button disabled={data === ''}>Button label</Button>
  );
}

如果 Component.js 不调用 onChange 函数,我将无法启用此 Button 并对其使用 fireEvent。

【问题讨论】:

    标签: reactjs react-testing-library


    【解决方案1】:

    你应该能够使用jest.spyOn来模拟HTMLCanvasElement.prototype.toDataURL的实现:

    我不确定您想针对您的模拟 toDataURL 方法运行哪种断言,但我假设您至少想检查它是否被正确调用。

    const dummyDataURL = 'data:image/png;base64,<...>';
    const toDataURLStub = jest
      .spyOn(HTMLCanvasElement.prototype, 'toDataURL')
      .mockImplementationOnce(() => {
        return dummyDataURL;
      });
    // Create your canvas and trigger your touchend event
    expect(toDataURLStub).toHaveBeenCalledWith('image/png');
    

    你可能还想确保你有一个 afterEach 块来恢复所有模拟,因为如果你的断言失败,它将阻止函数的其余部分运行(因此我选择不在结束时恢复存根上面的代码)。

    afterEach(() => {
      // This is effectively guaranteed to run even if
      // your test assertions fail
      jest.restoreAllMocks();
    });
    

    【讨论】:

    • 使用 spyOn(HTMLCanvasElement.prototype.toDataURL) 导致此错误:Cannot spy the undefined property because it is not a function; undefined given instead
    • 看起来正确的语法是jest.spyOn(HTMLCanvasElement.prototype, 'toDataURL')。现在我又遇到了另一个错误,但我仍然不确定它是否与此有关。
    • @JulianoNunesSilvaOliveira 啊是的,我很抱歉——我打错了函数签名。我已经编辑了我的答案来纠正这个问题。你得到的新错误是什么?
    • Component.js 实际上还有一些在 onTouchMove 和 onTouchStart 事件上调用的函数,其中之一使用 document.getElementById 获取画布元素的引用并从此画布获取 getContext。我将更新问题以添加这些行,但我认为我需要模拟我的功能组件的功能(不确定是否可能)。
    【解决方案2】:

    你用ref解决了吗?我有类似的测试问题。如果您在这里提供帮助,将不胜感激。谢谢

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-29
      • 2018-12-06
      • 2017-09-15
      • 2022-12-05
      • 2018-11-06
      • 1970-01-01
      • 2022-12-12
      相关资源
      最近更新 更多