Angular Unit Tests with Jest

Why Jest?

As you already know, the standard test runner provided with Angular is Karma. The main difference between the two testing platforms is how they operate. Karma runs the tests against a full browser, while Jest simply runs in your command line and gets access to web APIs through jsdom. Because of that, tests in Jest can be run in parallel, which helps accelerating your tests.

On top of that Jest aims to require minimal configuration and comes with a coverage report out of the box.

Getting started

I'm assuming you already created a new Angular application (ng new my-app). The first step we need to take is installing the dependencies:

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

After that, create a "jest.config.js" file in the root of your project with the following content:

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

Next, we need to create another file in the root directory called "setup-jest.ts" where we simply import the jest preset for Angular:

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

Now adjust your tsconfig.spec.json to be:

// tsconfig.spec.json
{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "./out-tsc/spec",
    // emitDecoratorMetadata needed for Jest to work correctly
    "emitDecoratorMetadata": true,
    "types": [
      "jest"
    ],
  },
  "include": [
    "src/**/*.spec.ts",
    "src/**/*.d.ts"
  ]
}

You probably noticed the "emitDecoratorMetadata" option which is a fix for this issue. Your tests will fail without setting this option (at least they do for me), with the error of "Can't resolve all parameters for [your-component]".

Before the last step, we need to remove the old Karma related libraries and files:

npm remove karma karma-chrome-launcher karma-coverage-istanbul-reporter karma-jasmine karma-jasmine-html-reporter
rm ./karma.conf.js ./src/test.ts

Finally, in your package.json file under test scripts replace "ng test" with "jest":

// package.json
"scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "watch": "ng build --watch --configuration development",
    "test": "jest"
  },

If you now run "npm test" from your command line, Jest will run your tests.

If you see the following warning, simply follow the recommendation:

ts-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`).

Remember that "ng test" will not work anymore as it's still configured to use Karma in your Angular.json file. If you want to configure "ng test" to use Jest, here is the npm package for the Angular builder to do that.

I hope todays tutorial helped you in setting up Jest for your Angular project. Please feel free to reach out if you encountered any errors following the steps above.

Take care,

Florian