DEV Community

Theoklitos Bampouris
Theoklitos Bampouris

Posted on

Setup Unit Testing Tools in Angular CLI Project

Originally published at https://www.bampouris.eu/blog/setup-unit-testing-angular


Every developer have to ensure that his/her application is working as expected. A safeguard to that purpose are unit tests.

The Defaults of an Angular CLI Generated Project

An Angular CLI generated project comes by default with Karma and Jasmine for unit testing. However, there are people who prefer other tools such as Jest.

I'm not going, in this post, to compare or choose the one over the other. I will only show you the steps to move from Karma/Jasmine to Jest. At the end, it's just a case of taste.

Remove Karma & Jasmine Related Packages

  • Uninstall the npm packages:
npm uninstall karma karma-chrome-launcher karma-coverage karma-jasmine karma-jasmine-html-reporter jasmine-core @types/jasmine
Enter fullscreen mode Exit fullscreen mode
  • Delete the no more needed Karma configuration files:
rm ./karma.conf.js ./src/test.ts
Enter fullscreen mode Exit fullscreen mode

Install Jest

npm i -D jest @types/jest jest-preset-angular @angular-builders/jest
Enter fullscreen mode Exit fullscreen mode
  • @types/jest: This package contains type definitions for Jest.
  • jest-preset-angular: It is Jest preset configuration and TypeScript preprocessor with source map support for Jest that lets you use Jest to test Angular projects.
  • @angular-builders/jest: Allows running ng test with Jest instead of Karma & Jasmine. The builder comes to provide zero configuration setup for Jest while keeping the workspace clear of boilerplate code.

To make use of @angular-builders/jest, the only we need to do is to change our angular.json file as below:

  }
},
"test": {
-  "builder": "@angular-devkit/build-angular:karma",
+  "builder": "@angular-builders/jest:run",
  "options": {
-    "main": "src/test.ts",
-    "polyfills": "src/polyfills.ts",
-    "tsConfig": "tsconfig.spec.json",
-    "karmaConfig": "karma.conf.js",
-    "inlineStyleLanguage": "scss",
-    "assets": ["src/favicon.ico", "src/assets"],
-    "styles": ["src/styles.scss"],
-    "scripts": []
+    "no-cache": true
  },
  "lint": {
Enter fullscreen mode Exit fullscreen mode

You may find details how to change the builder options here.

Setup Jest in our Project

We create a config file in project's root directory with the name jest.config.js:

module.exports = {
  preset: 'jest-preset-angular',
  setupFilesAfterEnv: ['<rootDir>/setup-jest.ts'],
};
Enter fullscreen mode Exit fullscreen mode

As you guess from the above configuration, we will now create setup-jest.ts in root directory:

import 'jest-preset-angular/setup-jest';
import './jest-global-mocks';
Enter fullscreen mode Exit fullscreen mode

The second import above is optional at first. Because jest-preset-angular uses JSDOM, which is different from normal browsers, we might need some global browser mocks to simulate the behaviors of real browsers in JSDOM. To add global mocks, we can create jest-global-mocks.ts and use it in our Jest setup.

You may find more information about jest-preset-angular in official docs and about Jest and JSDOM in this article.

Here is an example of jest-global-mocks.ts:

Object.defineProperty(window, 'CSS', { value: null });
Object.defineProperty(document, 'doctype', {
  value: '<!DOCTYPE html>',
});
Object.defineProperty(window, 'getComputedStyle', {
  value: () => {
    return {
      display: 'none',
      appearance: ['-webkit-appearance'],
    };
  },
});
Object.defineProperty(document.body.style, 'transform', {
  value: () => {
    return {
      enumerable: true,
      configurable: true,
    };
  },
});
Enter fullscreen mode Exit fullscreen mode

Finally, in tsconfig.spec.json file, we have to take care of at least two things:

  • Replace jasmine in types array with jest, as we want our tests to be type-checked against Jest typings and not Jasmine.
  • Remove test.ts entry from files array. This file was responsible for Karma setup, we don't need it here anymore.
"compilerOptions": {
  "outDir": "./out-tsc/spec",
  "types": [
-    "jasmine"
-  ]
+    "jest",
+    "node"
+  ],
+  "esModuleInterop": true,
+  "emitDecoratorMetadata": true,
},
"files": [
-  "src/test.ts",
  "src/polyfills.ts"
],
"include": [
Enter fullscreen mode Exit fullscreen mode

For other options you may check here.

Last But Not Least

A nice and powerful tool to simplify our Angular unit tests is Spectator:

  • Helps you get rid of all the boilerplate grunt work, leaving you with readable, sleek and streamlined unit tests.
  • Write tests for components, directives, services, and more, without having to learn TestBed, ComponentFixture, and DebugElement APIs.

We can install it with:

npm i -D @ngneat/spectator
Enter fullscreen mode Exit fullscreen mode

I hope in a future post to show a few examples of how we can use it and take advantage of its features.

Top comments (0)