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

Scu*_*Kay 7 jestjs angular angular9

我正在开发一个我们最近在 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)
Run Code Online (Sandbox Code Playgroud)

我安装 Jest 的步骤是:

  1. 安装 Jest 本身

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

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

  2. 更新了 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"
  ]
}
Run Code Online (Sandbox Code Playgroud)
  1. 添加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>/'
  })
};
Run Code Online (Sandbox Code Playgroud)
  1. 删除 karma.conf.js

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

  3. 从 ./src 中删除 test.ts

  4. 将“test”:“ng test”更改为“test”:“jest”

  5. 在./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
    };
  }
});
Run Code Online (Sandbox Code Playgroud)

无法运行的测试的一个示例如下:

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();
  });
});
Run Code Online (Sandbox Code Playgroud)

我不明白我做错了什么。我尝试了几个教程,还有一个使用@angular-builders/jest,但到目前为止还没有一个起作用。我有一种感觉,也许过渡到使用 Ivy 渲染器会导致问题,但我对此不确定。我在 Google 上似乎找不到遇到同样问题的人,所以这让我来到了 StackOverflow。这里有人知道如何修复该错误吗?

[编辑]

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

[编辑]

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

Mar*_*arc 0

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

    beforeEach(async(() => {
       TestBed.configureTestingModule({
         declarations: [ MenuComponent ],
         { provide: NgZone, useValue: { run(fn): any { return fn(); } }},
       })
       .compileComponents();
    }));
Run Code Online (Sandbox Code Playgroud)

如果这不起作用:

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

platformBrowserDynamic()
    .bootstrapModule(AppModule, { ngZone: 'noop' })
    .catch(console.error});
Run Code Online (Sandbox Code Playgroud)

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

// import 'zone.js/dist/zone';  // Included with Angular CLI.
Run Code Online (Sandbox Code Playgroud)