How to use Jest in Angular
Jest is a modern testing framework that offers faster test execution, better error messages, and snapshot testing compared to Karma/Jasmine. As the creator of CoreUI with over 12 years of Angular experience since 2014, I’ve migrated several large projects from Karma to Jest for improved developer experience. Jest runs tests in Node.js using jsdom instead of real browsers, making it significantly faster for unit tests. The migration requires installing Jest packages and configuring Angular to use Jest instead of Karma.
Replace Karma/Jasmine with Jest for faster Angular testing with snapshot support and improved DX.
Install Jest packages:
npm install --save-dev jest @types/jest jest-preset-angular
Create setup-jest.ts:
import 'jest-preset-angular/setup-jest'
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
}
}
})
Create jest.config.js:
module.exports = {
preset: 'jest-preset-angular',
setupFilesAfterEnv: ['<rootDir>/setup-jest.ts'],
testPathIgnorePatterns: ['/node_modules/', '/dist/'],
globals: {
'ts-jest': {
tsconfig: '<rootDir>/tsconfig.spec.json',
stringifyContentPathRegex: '\\.html$'
}
},
coverageDirectory: 'coverage',
transform: {
'^.+\\.(ts|js|html)$': 'jest-preset-angular'
},
moduleFileExtensions: ['ts', 'html', 'js', 'json', 'mjs'],
moduleNameMapper: {
'^@app/(.*)$': '<rootDir>/src/app/$1',
'^@environments/(.*)$': '<rootDir>/src/environments/$1'
},
collectCoverageFrom: [
'src/**/*.ts',
'!src/**/*.spec.ts',
'!src/main.ts',
'!src/polyfills.ts'
]
}
Update 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"
]
}
Update package.json:
{
"scripts": {
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage"
}
}
Remove Karma:
npm uninstall karma karma-chrome-launcher karma-coverage karma-jasmine karma-jasmine-html-reporter @types/jasmine
rm karma.conf.js
Example test with Jest:
import { TestBed } from '@angular/core/testing'
import { UserComponent } from './user.component'
describe('UserComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [UserComponent]
}).compileComponents()
})
it('should create', () => {
const fixture = TestBed.createComponent(UserComponent)
const component = fixture.componentInstance
expect(component).toBeTruthy()
})
it('should match snapshot', () => {
const fixture = TestBed.createComponent(UserComponent)
expect(fixture).toMatchSnapshot()
})
})
Best Practice Note
Jest is 2-3x faster than Karma for unit tests because it runs in Node.js instead of browsers. Use snapshot testing to catch unintended UI changes. Jest’s parallel test execution speeds up large test suites. The watch mode is more intelligent, only running tests affected by changes. For E2E tests requiring real browsers, continue using Cypress or Protractor. Jest mocking is simpler than Jasmine spies. This is how we optimize testing in large CoreUI Angular projects—using Jest for fast unit tests while maintaining a small Cypress suite for critical user flows.



