如何配置 jest jsdom 环境?

Posted

技术标签:

【中文标题】如何配置 jest jsdom 环境?【英文标题】:How to config jest jsdom environment? 【发布时间】:2021-10-05 13:57:27 【问题描述】:

我正在使用 jest 和 react 测试库来测试我的 react 应用程序。我想测试一个需要 ISR (nextJs getStaticProps) 来呈现的页面,所以我安装了next-page-tester 包。它正常渲染客户端渲染页面,但是当涉及到使用 ISR 渲染的页面时,发生了以下错误。 (我尝试在 jest.config.js 文件中添加 testEnvironment: 'jsdom' 并在我的测试文件顶部添加注释来配置 jsdom 环境)。

package.json
    "test": "jest --env=jsdom",
错误:

FIRESTORE (8.6.8) 内部断言失败:意外状态

  at fail (node_modules/@firebase/firestore/src/util/assert.ts:40:9)
  at hardAssert (node_modules/@firebase/firestore/src/util/assert.ts:54:5)
  at fromBytes (node_modules/@firebase/firestore/src/remote/serializer.ts:252:5)
  at fromWatchChange (node_modules/@firebase/firestore/src/remote/serializer.ts:475:25)
  at PersistentListenStream.Object.<anonymous>.PersistentListenStream.onMessage

(node_modules/@firebase/firestore/src/remote/persistent_stream.ts:581:25) 在 node_modules/@firebase/firestore/src/remote/persistent_stream.ts:461:21 在 node_modules/@firebase/firestore/src/remote/persistent_stream.ts:514:18 在 node_modules/@firebase/firestore/src/util/async_queue_impl.ts:168:14

下面的错误可能是使用了错误的测试环境, 见https://jestjs.io/docs/configuration#testenvironment-string。 考虑使用“jsdom”测试环境。

ReferenceError: document is not defined

  at Object.cleanupDOM (node_modules/next-page-tester/dist/makeRenderMethods.js:52:5)
  at Object.cleanup (node_modules/next-page-tester/dist/testHelpers.js:39:25)
jest.config.js:
module.exports = 
  verbose: true,
  testEnvironment: 'jsdom',
  setupFiles: ['./src/__mocks__/client.js'],
  setupFilesAfterEnv: ['./jest.setup.js', '@testing-library/jest-dom/extend-expect'],
  moduleDirectories: ['node_modules', 'src'],
  moduleNameMapper: 
    '\\.(css|less|scss|sass)$': 'identity-obj-proxy',
  ,

测试文件:

/**
 * @jest-environment jsdom
 */

import '@testing-library/jest-dom/extend-expect'
import  mockFirebase  from 'firestore-jest-mock'
import  getPage, initTestHelpers  from 'next-page-tester'
import  render, screen  from '../test-utils'

initTestHelpers()

mockFirebase(
  database: 
    topics: [
      
        id: 'IWkxBYYrA19IYeKPWEYx',
        all_day: false,
        closed: false,
        created_at:  seconds: 1626400885, nanoseconds: 372000000 ,
        description: 'test',
        en_title: 'test',
        en_description: 'test',
        event_date: 
          end_date:  seconds: 1626400859, nanoseconds: 372000000 ,
          start_date:  seconds: 1626400859, nanoseconds: 372000000 ,
        ,
        genre: 'information',
        title: 'test',
        topic_id: 'Ux6FPQgXL9sX6vm4V9Lk',
        updated_at:  seconds: 1626400885, nanoseconds: 373000000 ,
      ,
      
        id: 'Nwev6hr7m2hyc2oLblhC',
        all_day: false,
        closed: false,
        en_title: 'test',
        en_description: 'test',
        created_at:  seconds: 1626400885, nanoseconds: 372000000 ,
        description: 'test',
        event_date: 
          end_date:  seconds: 1626400859, nanoseconds: 372000000 ,
          start_date:  seconds: 1626400859, nanoseconds: 372000000 ,
        ,
        genre: 'information',
        title: 'test',
        topic_id: 'test',
        updated_at:  seconds: 1626400885, nanoseconds: 373000000 ,
      ,
      
        id: 'Nwev6hr7m2hyc2oLblhCee',
        all_day: false,
        closed: false,
        en_title: 'test',
        en_description: 'test',
        created_at:  seconds: 1626400885, nanoseconds: 372000000 ,
        description: 'test',
        event_date: 
          end_date:  seconds: 1626400859, nanoseconds: 372000000 ,
          start_date:  seconds: 1626400859, nanoseconds: 372000000 ,
        ,
        genre: 'information',
        title: 'test',
        topic_id: 'Ux6FPQgXL9sX6vm4V9Lk',
        updated_at:  seconds: 1626400885, nanoseconds: 373000000 ,
      ,
    ],
  ,
)

describe('Topics page', () => 
  it('should render topics page', async () => 
    const  page  = await getPage(
      route: '/topics',
    )
    render(page)
    expect(await screen.getByText(/topics/i)).toBeInTheDocument()
    screen.debug()
  )
)

/页面/主题:

import  Layout  from 'components/layout'
import  TopicsList  from 'components/organisms/topics'
import  fetchSelectTopics  from 'lib/topics'
import  GetStaticProps  from 'next'

const Topics = (props) => 
  const  topics  = props

  return (
    <Layout pageTitle='Topics' dark=true>
      <TopicsList topics=topics />
    </Layout>
  )


export const getStaticProps: GetStaticProps = async () => 
  const getTopics = await fetchSelectTopics('information')
  const topics = JSON.parse(JSON.stringify(getTopics))

  return 
    props:  topics: topics ,
    revalidate: 10,
  


export default Topics

【问题讨论】:

【参考方案1】:

我遇到了同样的问题,并且能够通过创建自定义 jsdom 环境来解决它。试试这个URL中的步骤

【讨论】:

以上是关于如何配置 jest jsdom 环境?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 javascript 中模拟内部 JSON 对象?

如何使用 Jest 在本机反应中模拟“react-native-config”库的配置数据?

Redux 使用 jest、nock、axios 和 jsdom 测试 multipart/form-data

如何仅通过一个 Jest 配置文件/设置使用多个 Jest 预设?

前端自动化测试框架 Jest 极简教程

如何在 SharePoint SPFx + react 项目中配置 jest 单元测试框架