单元测试因 .getContext() 未实现而引发错误

问题描述 投票:0回答:8

我正在使用 Jest 为使用画布元素的组件编写测试。当我运行如下所示的测试时,我不断收到错误。

Error: Not implemented: HTMLCanvasElement.prototype.getContext (without installing the canvas npm package)

据我了解,Jest 使用 jsdom 进行测试,如果您安装了 canvas 或 canvas 预构建的软件包,jsdom 与 canvas 兼容。

我已经尝试安装这些软件包中的每一个,但它们都没有解决该错误。我认为唯一可能出错的是 jsdom 找不到 canvas 或 canvas-prebuilt 包。有谁知道如何修复此错误或测试 jsdom 是否找到其他包?非常感谢!

javascript canvas jestjs jsdom
8个回答
88
投票

我的团队正在使用

create-react-app
,我们之前通过添加 npm 包
jest-canvas-mock
解决了这个问题。现在升级到react-scripts 3.4.1后,我们还必须向我们的
src/setupTests.ts
文件添加特定的导入:

import 'jest-canvas-mock';

59
投票

您可以在 jest 设置脚本中创建您自己的函数模拟

HTMLCanvasElement.prototype.getContext = () => { 
  // return whatever getContext has to return
};

14
投票

我的 Jest 测试遇到了类似的问题,并通过安装 jest-canvas-mock 解决了它。


14
投票

我已经通过安装 jest-canvas-mock

解决了这个问题

npm i --save-dev jest-canvas-mock

并在

package.json

上添加此配置
{
  "jest": {
    "setupFiles": [
      "jest-canvas-mock"
    ],
  }
}

6
投票

您可以将其创建为模拟,并且无需安装新包:

HTMLCanvasElement.prototype.getContext = jest.fn();

5
投票

以上两个答案都有效。但是,只是想补充一点,在 create-react-app 的情况下,它不支持 jest-canvas-mock 的 package.json 中 jest conf 所需的“setupFiles”。

我通过在调用 canvas 元素的每个测试文件中添加 import 语句来解决这个问题(在我的案例 3 中)。然后,我将导入语句移至 setupTests.js 文件并删除了该要求。


0
投票

我使用

react-scripts
3.0.1 遇到了同样的问题,并通过将
jest-canvas-mock
安装为
dev
依赖项并将其导入 (
import 'jest-canvas-mock'
) 到我的 app.test.js 文件(我从其中得到该错误)来解决它)只是因为在
setupTests.js
上导入它会不必要地在每个测试文件中导入包。


0
投票

好吧,我的答案来自左外野:

==> 使用 StoryBook <==

Canvas 是一个非常直观的组件

测试系统应该尽可能地模仿现实世界

因此,如果您实际上正在测试一些与用户相关且有利的内容,那么您可能会发现使用编写良好的 StoryBook 文件总体上更快、更容易,而不是模拟功能的测试。我认为这比使用计算机更能模拟现实生活,因此作为测试系统,它是更好的选择。

我在这里使用的一个例子是

disabled
属性可以在类似 Jest 的空间中进行测试,例如检查 aria 属性是否添加到 HTML 中,但是如果有人破坏了 CSS,那么测试将错过它.

事实上,画布只是视觉的,如果你想让它易于访问,你几乎必须编写一个全新的组件来描述以非视觉实体(人类或非人类)可以消化的方式显示的数据。否则,您只是屏蔽了世界人口的 25% 以及您可能想要抓取您网站的所有内容(尽管在我看来,人工智能将达到使这一点在几个月内过时的水平)。

然而,另一种解决方案将建立在模拟解决方案的基础上,那就是明确控制构建画布的JS,例如将其分解到util文件中,以便可以轻松地对它们进行单元测试。

但是,我会回到左场,指出 SVG 是一个替代选项,它实际上改善了几乎所有情况下的体验。对于初学者来说,这一切都在 DOM 中,并且使用 ForeignObject 您也可以添加 HTML。你可以坚持使用类似 Jest 的环境,尽管我个人仍然推荐 StoryBook(还有 QA 人员,可能来自用户池或客户,产品知识比技术更重要)。

我读到的建议是,Canvas 最适合显示大量数据点(10000 或更多)或游戏/动画等。在这篇由 JointJS 的 James Williams 撰写的优秀博客文章中,有更多 canvas 与 svg 的内容 包括总结点,由于链接失效原因:

  • SVG 的性能不一定较差,因为数以万计的数据点可能更好地聚集在屏幕尺寸上
  • SVG 并不像画布那样排斥设计师,因为他们每天都了解并使用这种格式
  • HTML 和 CSS 与 SVG 配合良好
  • SVG 尺度
  • canvas 一开始并不是一个开放标准

抱歉有点偏离主题。

© www.soinside.com 2019 - 2024. All rights reserved.