You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React+Testing-Library测试报错:无法读取null的_location属性

测试用例全部通过但仍抛出TypeError,导致CI返回错误码1

错误现象

本地及GitHub Actions执行测试时,所有测试用例均通过,但测试结束后会抛出TypeError: Cannot read properties of null (reading '_location'),最终导致进程退出码为1,CI流程失败。

错误栈信息

TypeError: Cannot read properties of null (reading '_location')
    at Window.get location [as location] (my_files\characterbuilder\node_modules\jest-environment-jsdom\node_modules\jsdom\lib\jsdom\browser\Window.js:375:79)
    at FetchInterceptor.<anonymous> (my_files\characterbuilder\node_modules\@mswjs\interceptors\src\interceptors\fetch\index.ts:52:9)
    at step (my_files\characterbuilder\node_modules\@mswjs\interceptors\lib\interceptors\fetch\index.js:59:23)
    at Object.next (my_files\characterbuilder\node_modules\@mswjs\interceptors\lib\interceptors\fetch\index.js:40:53)
    at fulfilled (my_files\characterbuilder\node_modules\@mswjs\interceptors\lib\interceptors\fetch\index.js:31:58)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at processImmediate (node:internal/timers:447:9)

GitHub Actions执行日志:

Run npm test

> characterbuilder@0.1.0 test
> react-scripts test

PASS src/App.test.js
  App component
    ✓ renders race dropdown (140 ms)
    ✓ selects a race and renders subrace dropdown (141 ms)
    ✓ renders class dropdown (28 ms)
    ✓ selects a class and renders subclass dropdown (104 ms)
    ✓ rolls stats and displays rolled values (136 ms)
    ✓ selects class and checks if proficiencies are displayed correctly (72 ms)
    ✓ selects class and the max amount of proficiencies, then checks if selecting more proficiencies is allowed (74 ms)
    ✓ checks if proficiency checkboxes all start disabled when no class has been selected (36 ms)

Test Suites: 1 passed, 1 total
Tests:       8 passed, 8 total
Snapshots:   0 total
Time:        2.628 s
Ran all test suites.
/home/runner/work/characterbuilder/characterbuilder/node_modules/jest-environment-jsdom/node_modules/jsdom/lib/jsdom/browser/Window.js:375
      return idlUtils.wrapperForImpl(idlUtils.implForWrapper(window._document)._location);
                                                                              ^

TypeError: Cannot read properties of null (reading '_location')
    at Window.get location [as location] (/home/runner/work/characterbuilder/characterbuilder/node_modules/jest-environment-jsdom/node_modules/jsdom/lib/jsdom/browser/Window.js:375:79)
    at FetchInterceptor.<anonymous> (/home/runner/work/characterbuilder/characterbuilder/node_modules/@mswjs/interceptors/src/interceptors/fetch/index.ts:52:9)
    at step (/home/runner/work/characterbuilder/characterbuilder/node_modules/@mswjs/interceptors/lib/interceptors/fetch/index.js:59:23)
    at Object.next (/home/runner/work/characterbuilder/characterbuilder/node_modules/@mswjs/interceptors/lib/interceptors/fetch/index.js:40:53)
    at fulfilled (/home/runner/work/characterbuilder/characterbuilder/node_modules/@mswjs/interceptors/lib/interceptors/fetch/index.js:31:58)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at processImmediate (node:internal/timers:447:9)

Node.js v18.16.0
Error: Process completed with exit code 1.

涉及的依赖文件代码

jest-environment-jsdom的Window.js中location属性逻辑

get location() {
      return idlUtils.wrapperForImpl(idlUtils.implForWrapper(window._document)._location);
}

@mswjs/interceptors的fetch拦截器核心代码片段

protected checkEnvironment() {
    return (
      typeof globalThis !== 'undefined' &&
      typeof globalThis.fetch !== 'undefined'
    )
  }

  protected setup() {
    const pureFetch = globalThis.fetch

    invariant(
      !(pureFetch as any)[IS_PATCHED_MODULE],
      'Failed to patch the "fetch" module: already patched.'
    )

    globalThis.fetch = async (input, init) => {
      const request = new Request(input, init)

      const url = typeof input === 'string' ? input : input.url
      const method = request.method

      this.log('[%s] %s', method, url)

      const body = await request.clone().arrayBuffer()

      const requestUrl = new URL(
        url,
        typeof location !== 'undefined' ? location.origin : undefined
      )

      // 后续业务逻辑省略
    }

GitHub Actions工作流配置

name: Continuous Integration

on:
  push:
    branches:
      - dev

jobs:
  build:
    runs-on: ubuntu-latest
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v2
      
      - name: Install dependencies
        run: npm ci
      
      - name: Install
        run: npm install
      
      - name: run tests
        run: npm test

已尝试的解决方案

  • 在setupTests.js中添加window.URL.createObjectURL = function () {};和jest.spyOn(window, "close").mockImplementation(jest.fn());
  • 简化测试用例,仅保留无实际逻辑的单测试用例,问题仍未解决

注:未修改任何依赖文件,项目核心代码位于dev分支,业务代码在App.js,测试文件为App.test.js,Mock服务器配置在setupServer.js。

内容的提问来源于stack exchange,提问作者marijnjc88

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 11:37:20