为啥 Jest 不让我使用节点测试环境,即使他们自己更改了它?

Posted

技术标签:

【中文标题】为啥 Jest 不让我使用节点测试环境,即使他们自己更改了它?【英文标题】:Why Jest is not letting me use node testing environment even though they changed it themselves?为什么 Jest 不让我使用节点测试环境,即使他们自己更改了它? 【发布时间】:2022-01-18 13:53:50 【问题描述】:

我正在尝试使用 Jest 在 Next.js 中测试一个 React 组件。

Jest officially announced 他们正在将默认测试环境更改为 Node:

因此,我们将更改默认测试环境 "jsdom""node"

我需要使用 Node 环境,他们不让我使用。

我收到以下错误:

  ● basic test

    The error below may be caused by using the wrong test environment, see https://jestjs.io/docs/configuration#testenvironment-string.
    Consider using the "jsdom" test environment.
    
    ReferenceError: document is not defined

      40 | it("basic test", async () => 
      41 |   render(<Hellopage />);
    > 42 |   expect(true).toBe(true);
         |                 ^
      43 |   screen.debug();
      44 | );
      45 |

      at Object.render (node_modules/@testing-library/react/dist/pure.js:83:5)
      at Object.<anonymous> (components/__test__/hellopage.test.tsx:42:17)

我需要使用 node 的原因是 Firebase Firestore 在 JSDOM 下不工作。

我该如何解决这个错误?

【问题讨论】:

让你使用Node环境。它失败了,因为该环境不包含诸如 document 之类的定义,它们是 DOM API 的一部分(因此由 JSDOM 提供)并且 not 在 Node. @jonrsharpe 有没有办法让我获得这些定义并仍然使用节点,因为 firebase 需要它进行测试? 您必须自己将它们提供到全局范围内进行测试。基本上,您将重写 JSDOM 提供的一些子集。目前尚不清楚您遇到的具体问题是什么促使您朝这个方向发展。你最好用minimal reproducible example 询问,这可能是XY problem。 @jonrsharpe 当我使用 jsdom 测试环境时出现错误:“FIRESTORE (9.1.3) INTERNAL ASSERTION FAILED: Unexpected state”。不好意思,我很迷茫,jest自带的默认测试环境怎么不能渲染简单的react组件,开发者还需要测试什么? 因为现在默认的测试环境是Node,它是为了……一个Node环境。 不是 DOM 环境,这是 React(无论多么简单的组件)运行的地方。为 DOM 环境测试代码的开发人员应该使用提供 DOM API 的测试环境,例如 JSDOM。 【参考方案1】:

如果你对 React 组件进行单元测试,你肯定需要 jsdom 测试环境。但是您要实现的是测试 UI,而不是数据库访问。如果您访问外部资源,则不再是单元测试,而是集成测试。

您要做的是将 UI 组件与数据库查询分离,这样您的测试就可以提供假数据而不会碰到数据库。同样,如果您的组件向数据库写入任何内容,它可以通过您的测试提供的功能而不是您在生产中使用的功能来完成。

【讨论】:

以上是关于为啥 Jest 不让我使用节点测试环境,即使他们自己更改了它?的主要内容,如果未能解决你的问题,请参考以下文章

React Jest 测试因 MSW 失败

如何在 Jest 的自定义测试环境文件中使用 TypeScript?

使用 Jest 测试时未定义全局节点配置变量

为啥不显示我的 Jest 自定义匹配器的“消息”?

为啥 Jest 在测试“Colyseus”游戏时会出现这个错误?

使用 Jest 运行测试时,为啥 Trix 编辑器不会安装在 Vue 组件中?