在 Angular 9 中迁移到 Jest 会出现“未定义区域”错误

Posted

技术标签:

【中文标题】在 Angular 9 中迁移到 Jest 会出现“未定义区域”错误【英文标题】:Migrating to Jest in Angular 9 gives "Zone is not defined" error 【发布时间】:2020-09-05 11:35:18 【问题描述】:

我正在处理一个我们最近在 Angular 9 中启动的项目,该项目是使用 Angular CLI 生成的。我想使用 Jest 而不是 Karma 来运行我的测试,因为在我看来,在你的构建管道中设置 Karma 的工作量太大(几年前我浪费了很多时间试图让 Karma 运行)。

我在尝试运行 Jest 时遇到错误:

ReferenceError: Zone is not defined

      at node_modules/zone.js/dist/zone.js:670:5
      at performance (node_modules/zone.js/dist/zone.js:8:9)
      at Object.<anonymous> (node_modules/zone.js/dist/zone.js:9:2)

我安装 Jest 的步骤是:

    自行安装 Jest

npm install -D jest jest-preset-angular @types/jest ts-jest

    从 package.json 中移除所有 karma/jasmine 库

    更新了 tsconfig.spec.json:


  "extends": "./tsconfig.json",
  "compilerOptions": 
    "outDir": "./out-tsc/spec",
    "types": [
      "jest",
      "node"
    ],
    "esModuleInterop": true,
    "emitDecoratorMetadata": true
  ,
  "files": [
    "src/polyfills.ts"
  ],
  "include": [
    "src/**/*.spec.ts",
    "src/**/*.d.ts"
  ]

    添加 jest.config.js:
const  pathsToModuleNameMapper  = require('ts-jest/utils');
const  compilerOptions  = require('./tsconfig');

module.exports = 
  preset: 'jest-preset-angular',
  roots: ['<rootDir>/src/'],
  testMatch: ['**/+(*.)+(spec).+(ts)'],
  setupFilesAfterEnv: ['<rootDir>/src/setupJest.ts'],
  collectCoverage: true,
  coverageReporters: ['html'],
  coverageDirectory: 'coverage/my-app',
  moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths || , 
    prefix: '<rootDir>/'
  )
;

    删除 karma.conf.js

    从 angular.json 中的架构师移除测试

    从 ./src 中删除 test.ts

    将“test”:“ng test”改为“test”:“jest”

    在 ./src 中添加了 setupJest.ts:

import 'jest-preset-angular';

Object.defineProperty(window, 'CSS', value: null);
Object.defineProperty(window, 'getComputedStyle', 
  value: () => 
    return 
      display: 'none',
      appearance: ['-webkit-appearance']
    ;
  
);

Object.defineProperty(document, 'doctype', 
  value: '<!DOCTYPE html>'
);
Object.defineProperty(document.body.style, 'transform', 
  value: () => 
    return 
      enumerable: true,
      configurable: true
    ;
  
);

运行失败的测试示例如下:

import  async, ComponentFixture, TestBed  from '@angular/core/testing';

import  MenuComponent  from './menu.component';

describe('MenuComponent', () => 
  let component: MenuComponent;
  let fixture: ComponentFixture<MenuComponent>;

  beforeEach(async(() => 
    TestBed.configureTestingModule(
      declarations: [ MenuComponent ]
    )
    .compileComponents();
  ));

  beforeEach(() => 
    fixture = TestBed.createComponent(MenuComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  );

  it('should create', () => 
    expect(component).toBeTruthy();
  );
);

我不知道我做错了什么。我尝试了几个教程,还有一个使用@angular-builders/jest,但到目前为止都没有。我有一种感觉,使用 Ivy 渲染器的过渡可能会导致问题,但我不确定。我似乎在 Google 上找不到任何有同样问题的人,所以这把我带到了 ***。这里有人知道如何修复错误吗?

[编辑]

我在https://github.com/kayvanbree/jest-problem创建了我的问题的最小预生产

[编辑]

顺便说一句,这个问题的答案没有帮助:How to fix "zone is not defined" in this project

【问题讨论】:

【参考方案1】:

请尝试在您的 configureTestingModule 中添加“provide: NgZone”:

    beforeEach(async(() => 
       TestBed.configureTestingModule(
         declarations: [ MenuComponent ],
          provide: NgZone, useValue:  run(fn): any  return fn();  ,
       )
       .compileComponents();
    ));

如果效果不好:

只是一个快速测试:您可以将此“noop”配置添加到您的应用引导程序中吗?

platformBrowserDynamic()
    .bootstrapModule(AppModule,  ngZone: 'noop' )
    .catch(console.error);

请在 polyfill.ts 中注释掉这一行

// import 'zone.js/dist/zone';  // Included with Angular CLI.

【讨论】:

不幸的是,这不起作用。仍然收到Zone is not defined 错误。 如果我添加 'noop' 配置(在 main.ts 中)并注释掉 polyfill,它仍然会给出相同的错误。我在github.com/kayvanbree/jest-problem 上传了我的问题的最小复制品 我想我有东西。有一个关于 jest 26 未使用 ts-jest 测试的警告。降级到 25 并且可以正常工作。 我的回答完全错误。我会在今天晚些时候尝试找到答案。现在必须工作......【参考方案2】:

原来这是版本问题。

我已经安装了:

"@types/jest": "^25.2.2",
"jest": "^26.0.1",

似乎这些版本不想一起工作。它还警告说 jest 26 尚未使用 ts-jest 进行测试。

将 Jest 降级到 ^25.0.0 解决了这个问题。

【讨论】:

我试过这个,但我仍然得到一个错误:找不到模块'ts-jest/utils',你安装了什么版本的 jest-preset-angular?还是什么 ts-jest 版本?

以上是关于在 Angular 9 中迁移到 Jest 会出现“未定义区域”错误的主要内容,如果未能解决你的问题,请参考以下文章

从 Jasmine/Karma 迁移到 Jest 是不是可行?

Jest 单元测试中的 Angular 循环依赖问题

Jest - Angular 9 - 类构造函数 SomeComponentClass 不能在没有'new'的情况下被调用

在 Jest 测试之前无法加载 Google Maps API

在 Angular 7 中使用 Jest 进行测试时缺少 Kendo Intl Service 的语言环境信息

将 Angular 8 应用程序迁移到 9 的奇怪问题