为React项目运行Jest测试时出现“ ReferenceError:未定义窗口”

问题描述

我有一些Jest测试,用于测试应用程序中与firebaseui完全无关的功能,并且不需要浏览器窗口即可执行。我在应用程序的其他无关部分中使用firebaseui

话虽如此,即使我没有调用任何与firebaseui相关的代码或需要浏览器的代码,当我尝试运行其中一个测试时,firebaseui也会引发错误"ReferenceError: window is not defined"

我了解Jest测试在Node.js环境中运行,因此浏览器窗口根本不存在。但是,由于我的Jest测试没有调用任何firebaseui代码,因此这不应该发生。

有人对此问题有任何建议吗?有没有办法用Jest模拟虚拟浏览器窗口?

这是测试文件

import '../../../../cbjs/setup_test'
import {getCenter,rgbanormalizedToCSS,templateStructToNewCollage} from "./template_converter";
import {Point,Size} from "@piccollage/cbjs";
import {serverStringToStruct} from "../string_struct_converters";
import {ImageScrap} from "../../collage_editor/models/image_scrap";

// Todo: can't run tests from this file (Firebase error => window is not defined in ref_store constructor)

it("rgbanormalizedToCSS works",() => {
  expect(rgbanormalizedToCSS([0,0.5,0.3,0.4]))
    .toBe("rgba(0,128,77,0.4")
})

it("getCenter works",() => {
  expect(getCenter([0,0],[100,100]))
    .toBe(new Point(50,50))
})

it("templateStructToNewCollage works (just a single ImageScrap)",() => {
  const struct = serverStringToStruct("../test_files/test.plist",true)

  console.log(struct)

  const collage = templateStructToNewCollage('0',struct)

  expect(collage.size$.value).toBe(new Size(300,300))
  expect(collage.ownerId).toBe('0')
  expect(collage.backgroundURL$.value).toBe("photo-framework:/AAF82513-DA99-4F71-A371-7CCED92F4D52/L0/001")
  expect(collage.scraps$.value.length).toBe(1)

  const scrap = collage.scraps$.value[0]

  expect(scrap instanceof ImageScrap).toBeTruthy()
  expect(scrap.sizeBase$.value).toBe(new Size(300,58.843537414965986))
  expect(scrap.positioning$.value.point).toBe(new Point(396.9729729729729,518.6104045537717))
  expect(scrap.positioning$.value.rotation).toBe(0)
  expect(scrap.positioning$.value.scale).toBe(1.8990109511630093)
  expect(scrap.z$.value).toBe(1)
  expect((scrap as ImageScrap).imageSourceUrl$.value)
    .toBe("photo-framework:/687200F1-2A1C-40A0-BF76-B1D678C64799/L0/001")
})

这是堆栈跟踪:

    ReferenceError: window is not defined

      at node_modules/firebaseui/dist/npm.js:1:270
      at node_modules/firebaseui/dist/npm.js:26:301
      at Object.<anonymous> (node_modules/firebaseui/dist/npm.js:460:359)
      at Object.<anonymous> (node_modules/@piccollage/cbjs/dist/src/firebaseAuth.js:15:33)

jest.config.js:

module.exports = {
  preset: 'ts-jest',testEnvironment: 'node',transformIgnorePatterns: [
    'node_modules/(?!(cbjs)/)',],transform: {
    "^.+\\.(ts|js|jsx)$": "ts-jest"
  },modulefileExtensions: ["ts","tsx","js","jsx","json","node"],};

解决方法

$(location).attr(pathname);是一个全局浏览器对象,在nodeJS运行时上使用Jest运行测试时未定义。通常,可以使用提供这些全局变量的jsdom env来运行jest,在cli的window上使用应该可以解决问题。至于lib​​,您可能想使用玩笑的配置完全模拟它,请参阅文档:https://jestjs.io/docs/en/manual-mocks#mocking-node-modules。就像在项目根目录中的正确位置以及 mocks 目录中的node_modules处创建文件一样简单。