I'm working on a project that we recently started in Angular 9, generated using Angular CLI. I want to run my tests using Jest instead of Karma, because in my opinion, Karma is too much work to set up in your build pipelines (I've had many wasted hours trying to get Karma to run a couple of years ago).
I'm getting an error though when I try to run 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)
The steps I took to install Jest are:
- Install Jest itself
npm install -D jest jest-preset-angular @types/jest ts-jest
Remove all karma/jasmine libraries from package.json
Updated 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"
]
}
- Add 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>/'
})
};
Remove karma.conf.js
Remove test from architect in angular.json
Remove test.ts from ./src
Change "test": "ng test" to "test": "jest"
Added setupJest.ts in ./src:
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
};
}
});
An example of a test that fails to run is this one:
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();
});
});
I can't figure out what I am doing wrong. I tried several tutorial, also one using @angular-builders/jest, but none have worked so far. I have a feeling that maybe the transition to using the Ivy renderer is causing problems, but I am not sure about that. I can't seem to find anyone on Google with the same problem so this brings me to StackOverflow. Does anybody here know how to fix the error?
[edit]
I created a minimal preproduction of my problem at https://github.com/kayvanbree/jest-problem
[edit]
The answers to this question did not help by the way: How to fix "zone is not defined" in this project