Setup Jest in Angular application

Scott Jung
4 min readNov 2, 2021

--

I had Angular applications and wanted to test and collect coverage with Jest. There are various ways to integrate Jest into Angular and I found jest-preset-angular worked well for me.

This document is a step-by-step execution note.

1. Create an Angular Application

Create an angular app and run npm install. The angular version is 12 in the laptop at the time of writing this document.

$ ng --version
...
Package Version
------------------------------------------------------
@angular-devkit/architect 0.1202.12 (cli-only)
@angular-devkit/core 12.2.12 (cli-only)
@angular-devkit/schematics 12.2.12 (cli-only)
@schematics/angular 12.2.12 (cli-only)
$ ng new new-app
...
$ cd new-app
$ npm install

2. Install jest packages

Install jest, jest-preset-angular and @types/jest in devDependencies.

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

3. Uninstall karma and jasmine packages

Open package.json and find all karma and jasmine packages. Remove them using npm remove command.

$ npm remove @types/jasmine jasmine-core karma karma-chrome-launcher karma-coverage karma-jasmine karma-jasmine-html-reporter

4. Create 2 jest setup files

4.1 /jest.config.js

In your project root, create /jest.config.js (.js javascript file) with the following contents.
(NOTE: The file name is reserved by jest, and jest looks up this file for configuration.)

// jest.config.js (javascript file)
module.exports = {
preset: 'jest-preset-angular',
setupFilesAfterEnv: ['<rootDir>/setup-jest.ts'],
};

4.2 /setup-jest.ts

In your project root, create /setup-jest.ts with the following contents.
(INFO: You may change the filename with your preference as long as the file name is matched in the jest.config.js)

// setup-jest.ts
import 'jest-preset-angular/setup-jest';

5. Update files

5.1 /tsconfig.spec.json

(1) Change types from “jasmine” to “jest”.
(2) Remove files.

// Original file created by 'ng new' command.
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/spec",
"types": ["jasmine"]
},
"files": ["src/test.ts", "src/polyfills.ts"],
"include": ["src/**/*.spec.ts", "src/**/*.d.ts"]
}

The following is after the changes.

// After the changes
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/spec",
"types": ["jest"]
},
"include": ["src/**/*.spec.ts", "src/**/*.d.ts"]
}

5.2 /tsconfig.json

Add “esModuleInterop”: true in the CompilorOptions to remove a warning message. (See the warning message in Appendix)

{
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"sourceMap": true,
"declaration": false,
"downlevelIteration": true,
"experimentalDecorators": true,
"moduleResolution": "node",
"importHelpers": true,
"target": "es2017",
"module": "es2020",
"lib": ["es2018", "dom"],
"esModuleInterop": true
},
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
"strictInjectionParameters": true,
"strictInputAccessModifiers": true,
"strictTemplates": true
},
"types": ["jest"]
}

5.3 /package.json

Change the test script from ng test to jest

"scripts": {
"test": "ng test"
},
==>"scripts": {
"test": "jest --coverage"
},

6. Remove 2 files

Remove “/src/test.ts” and “/karma.config.js”.

7. Run jest with coverage option

Run npm run test, which invokes the script “jest --coverage

$ npm run test> new-app@0.0.0 test C:\new-app
> jest --coverage
PASS src/app/app.component.spec.ts
AppComponent
√ should create the app (140 ms)
√ should have as title 'new-app' (82 ms)
√ should render title (57 ms)
--------------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
--------------------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
app.component.html | 100 | 100 | 100 | 100 |
app.component.ts | 100 | 100 | 100 | 100 |
--------------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 3 passed, 3 total
Snapshots: 0 total
Time: 3.214 s
Ran all test suites.

A. Appendix (Troubleshooting)

A1. ts-jest[config] (WARN) message TS151001:

  • When you run jest, if you see this warning message,
$ jest --coveragets-jest[config] (WARN) message TS151001: If you have issues related to imports, you should consider setting `esModuleInterop` to `true` in your TypeScript configuration file (usually `tsconfig.json`). See https://blogs.msdn.microsoft.com/typescript/2018/01/31/announcing-typescript-2-7/#easier-ecmascript-module-interoperability for more information.

in the /tsconfig.json file, set “esModuleInterop” to true.

// tsconfig.json
{
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"sourceMap": true,
"declaration": false,
"downlevelIteration": true,
"experimentalDecorators": true,
"moduleResolution": "node",
"importHelpers": true,
"target": "es2017",
"module": "es2020",
"lib": ["es2018", "dom"],
"esModuleInterop": true
},
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
"strictInjectionParameters": true,
"strictInputAccessModifiers": true,
"strictTemplates": true
},
"types": ["jest"]
}

A2. If you create /jest.config.js incorrectly with .ts extension.

$ jest --coverageError: Jest: Failed to parse the TypeScript config file C:\new-app\jest.config.ts
Error: Jest: 'ts-node' is required for the TypeScript configuration files. Make sure it is installed
Error: Cannot find module 'ts-node'
Require stack:
- C:\new-app\node_modules\jest-config\build\readConfigFileAndSetRootDir.js
- C:\new-app\node_modules\jest-config\build\index.js
- C:\new-app\node_modules\jest\node_modules\jest-cli\build\init\index.js
- C:\new-app\node_modules\jest\node_modules\jest-cli\build\cli\index.js
- C:\new-app\node_modules\jest\node_modules\jest-cli\bin\jest.js
- C:\new-app\node_modules\jest\bin\jest.js
at readConfigFileAndSetRootDir (C:\new-app\node_modules\jest-config\build\readConfigFileAndSetRootDir.js:118:13)
at async readConfig (C:\new-app\node_modules\jest-config\build\index.js:233:18)
at async readConfigs (C:\new-app\node_modules\jest-config\build\index.js:420:26)
at async runCLI (C:\new-app\node_modules\@jest\core\build\cli\index.js:132:59)
at async Object.run (C:\new-app\node_modules\jest\node_modules\jest-cli\build\cli\index.js:155:37)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! new-app@0.0.0 test: `jest --coverage`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the new-app@0.0.0 test script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

Change the filename “jest.config.ts” to “jest.config.js” (javascript file)

--

--