库中的单元测试组件时生成的测试失败

Generated test fails when unit testing component inside the library

我的项目是使用 nx 原理图创建的,我在库中有一些组件,我想使用 jest.js 对其进行单元测试。每个测试都失败并出现以下错误:

● MyComponent › should create

    Failed: "Zone is needed for the async() test helper but could not be found. Please make sure that your environment includes zone.js/dist/zone.js"

       7 |   let fixture: ComponentFixture<MyComponent>;
       8 | 
    >  9 |   beforeEach(async(() => {
         |   ^
      10 |     TestBed.configureTestingModule({
      11 |       declarations: [ MyComponent ]
      12 |     })

      at Env.beforeEach (node_modules/jest-jasmine2/build/jasmineAsyncInstall.js:41:24)
      at Suite.<anonymous> (libs/componentlib/src/lib/components/my-component/my-component.component.spec.ts:9:3)
      at Object.<anonymous> (libs/componentlib/src/lib/components/my-component/my-component.component.spec.ts:5:1)

  ● MyComponent › should create

    TypeError: Cannot read property 'getComponentFromError' of null

      at TestBedViewEngine._initIfNeeded (../../packages/core/testing/src/test_bed.ts:393:46)
      at TestBedViewEngine.createComponent (../../packages/core/testing/src/test_bed.ts:594:10)
      at Function.TestBedViewEngine.createComponent (../../packages/core/testing/src/test_bed.ts:247:36)
      at Object.<anonymous> (libs/componentlib/src/lib/components/my-component/my-component.component.spec.ts:17:23)

  ● MyComponent › should create

    expect(received).toBeTruthy()

    Received: undefined

      21 | 
      22 |   it('should create', () => {
    > 23 |     expect(component).toBeTruthy();
         |                       ^
      24 |   });
      25 | });
      26 | 

      at Object.<anonymous> (libs/componentlib/src/lib/components/my-component/my-component.component.spec.ts:23:23)

我已经尝试在规范文件中导入 zone.js、导入模块、删除异步、在每次测试前重置测试环境,但一切都失败了,并出现了一些不同的错误。我还应该提到我正在使用 vmware 的清晰度组件。

这是 .spec 文件:

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

import { MyComponent } from './my-component.component';

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

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ MyComponent ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(MyComponent);
    component = fixture.componentInstance;
  });

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

我期待在使用 nx 时这应该能像预期的那样工作。我在这里错过了什么?

我找到了解决办法!

问题是在创建 nx 工作区时,jest 没有立即配置。所以我采取了以下步骤使其工作:

1.安装 jest-zone-patch

npm install jest-zone-patch --save-dev

2。编辑文件

对于每个库,您必须将 test-setup.ts 文件编辑为如下所示:

import 'zone.js/dist/zone.js';
import 'zone.js/dist/proxy';
import 'zone.js/dist/sync-test';
import 'zone.js/dist/async-test.js';
import 'zone.js/dist/proxy.js';

import 'jest-zone-patch';
import 'jest-preset-angular';
import './jestGlobalMocks';

此外,将 setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'] 添加到您的库的 jest.config.js 文件中,使其看起来像这样:

module.exports = {
  name: 'my-library',
  preset: '../../../jest.config.js',
  coverageDirectory: '../../../coverage/libs/administration/identification',
  setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts']
};

并将 jestGlobalMocks.ts 文件添加到与 test-setup.ts 文件相同的文件夹中。你可以找到它 here,或者直接复制下面的代码:

Object.defineProperty(window, 'CSS', {value: null});
Object.defineProperty(document, 'doctype', {
  value: '<!DOCTYPE html>'
});
Object.defineProperty(window, 'getComputedStyle', {
  value: () => {
    return {
      display: 'none',
      appearance: ['-webkit-appearance']
    };
  }
});
/**
 * ISSUE: https://github.com/angular/material2/issues/7101
 * Workaround for JSDOM missing transform property
 */
Object.defineProperty(document.body.style, 'transform', {
  value: () => {
    return {
      enumerable: true,
      configurable: true,
    };
  },
});

3。更改规范文件

将生成的规范文件更改为如下内容:

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

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [MyComponent]
    })
      .compileComponents()
      .then(() => {
        fixture = TestBed.createComponent(MyComponent);
        component = fixture.componentInstance;

        fixture.detectChanges();
      });
  }));

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

这样,在 compileComponents promise 完成后创建组件和夹具,从而避免竞争条件和潜在的 undefined 单元测试中的 'should create' 错误.

4. 运行库测试

最后,您可以 运行 您的测试,希望它会通过。

ng test my-library

希望这对某人有所帮助。

我刚遇到同样的问题

Using Nrwl's Nx to scaffold a new application plus a "feature-shell" library (the design pattern suggested by Nx's "Enterprise Angular Monorepo Patterns" 书),我也很困惑为什么我的 Jest 单元测试 Angular 组件 类 在 apps/ 中开箱即用,但是不是 libs/.

我可能找到了一个更简单的解决方案:

查看工作区根目录中 angular.json 的内部。注意 属性 projects.<your-app>.architect.test.options.setupFile。它的值应该类似于 "apps/<your-app>/src/test-setup.ts".

对我有用的解决方案是将 属性 和 angular.json 中的值添加到 projects.<your-lib>.architect.test.options

示例解决方案

// angular.json
{
  ...
  "projects": {
    "my-app": {
      ...
      "architect": {
        ...
        "test": {
          ...
          "setupFile": "apps/my-app/src/test-setup.ts" // <- This was already here...
        }
      }
    },
    "my-lib": {
      ...
      "architect": {
        ...
        "test": {
          ...
          "setupFile": "apps/my-app/src/test-setup.ts" // <- ...and I just added it here
        }
      }
    }
  }
}

希望 one-liner 也适合你!

如果有人在 Angular 11 上使用 Jest 并遇到此问题,请帮我解决这个问题。

确保我的 package.json 文件中有这两个属性。

{
  "jest": {
    "preset": "jest-preset-angular",
    "setupFilesAfterEnv": [
      "<rootDir>/setupJest.ts"
    ],
  }
}

setupJest.ts

import 'jest-preset-angular'

还要确保您的 jest 配置不包含 "testEnvironment": "node",。我从一个节点项目中复制了它,它也破坏了我的测试。