Setting up Jest for an Angular projectorCustom

Setting up Jest for Angular seems straightforward according to different online guides. It involves the following steps:

ng new jest-test
cd jest-test
npm i -D jest jest-preset-angular

Make changes to package.json:

"test": "jest",
[...]
"jest": {
    "preset": "jest-preset-angular",
    "setupTestFrameworkScriptFile": "./src/setup-jest.ts"
},

Include code in setup-jest.ts:

import 'jest-preset-angular';

Upon running npm test, I encounter the following error:

Jest encountered an unexpected token

This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.

By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".

Here's what you can do:
 • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
 • If you need a custom transformation specify a "transform" option in your config.
 • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/en/configuration.html

Details:

jest-test/src/app/app.component.spec.ts:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import { TestBed, async } from '@angular/core/testing';
                                                                                                ^

SyntaxError: Unexpected token {

  at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:403:17)

I've attempted multiple configurations found online, but they all return this same error message.

Please advise if additional information is needed.

Answer №1

If you are using Angular CLI, incorporating this library can greatly simplify your Jest setup.
With this library, you can eliminate the need for boilerplate code associated with Jest configuration and seamlessly run tests using Angular CLI (ng test).
This also streamlines the process of setting up Jest, saving you valuable time.

If you encounter a specific error, it may be linked to your tsconfig.spec.json. Ensure that you have updated the module field to commonjs as Jest requires this adjustment to function properly.

To delve deeper into this topic, refer to this informative article.

Disclaimer: I am the creator of this library.

Answer №2

A few weeks back, I experimented with the techniques outlined in this insightful blog post.

While the process was seamless, I ultimately decided to stick with Jasmine/Karma instead of switching to Jest for a couple of reasons:

  • Jest doesn't support running unit tests on multiple real browsers (You can find more details in the discussion on the Jest Repository)
  • With Jasmine, I have the flexibility to write end-to-end tests using tools like Protractor or Selenium-Webdriver

Answer №3

After switching to Ionic, I wanted to integrate Ionic 4 and Angular 6 with Jest for testing. I stumbled upon this insightful blog post by Brian Love which guided me through the process successfully. In my case, I customized my Jest configuration in an external file and made some tweaks to suit my needs, resulting in my tests now running smoothly within Angular 6.

module.exports = {
    collectCoverage: true,
    collectCoverageFrom: [
        "src/**/*.ts"
    ],
    coverageDirectory: "<rootDir>/coverage/",
    coveragePathIgnorePatterns: [
        "node_modules",
        "test-config",
        "<rootDir>/src/app/interfaces",
        "jestGlobalMocks.ts",
        ".module.ts",
        "<rootDir>/src/app/main.ts"
    ],
    preset: "jest-preset-angular",
    roots: ['src'],
    setupTestFrameworkScriptFile: "<rootDir>/src/setup-jest.ts",
    transformIgnorePatterns: [
        "node_modules/(?!(@ionic-native|@ionic|angularfire2)/)"
    ]
}

Answer №4

When I embarked on a new Angular project, I decided to integrate Jest for Unit tests. Adapting the configuration from an older project was quite the task as I had to make it compatible with Angular 13 and Jest 27.

Here are the steps I took to configure the setup. While not all of them may be imperative, I wanted to document everything I did for reference:

  1. Update the package.json file by adding the following script under scripts:

    "test": "jest  --coverage --config ./jest.config.js"
    
  2. Eradicate all karma dependencies from the package.json.

  3. Add the following packages to the devDependencies section in package.json (you might find newer versions, but these were the latest at the time of my setup):

    "@babel/core": "~7.16.12",
    "@babel/preset-env": "~7.16.11",
    "@babel/preset-typescript": "~7.16.7",
    "@types/jest": "~27.4.0",
    "babel-jest": "~27.4.6",
    "jest": "~27.4.7",
    "jest-preset-angular": "~11.1.0",
    "ts-jest": "~27.1.3",
    
  4. In tsconfig.spec.ts, include the following lines under compilerOptions / types:

    "jest",
    "node"
    
  5. Remove the entry for src/test.ts under files in tsconfig.spec.ts.

  6. Delete the file src/test.ts.

  7. Create a new file named jest.config.js and populate it with the necessary configuration:

    module.exports = {
      globalSetup: 'jest-preset-angular/global-setup',
      cacheDirectory: "<rootDir>/jest/cache",
      clearMocks: true,
      collectCoverage: true,
      coverageDirectory: "<rootDir>/jest/report",
      globals: {
        "ts-jest": {
          tsconfig: "<rootDir>/tsconfig.spec.json",
        }
      },
      moduleFileExtensions: ["ts", "js", "json"],
      preset: "jest-preset-angular",
      setupFilesAfterEnv: ["<rootDir>/setup-jest.ts"],
      "transform": {
        "^.+\\.(ts|js)$": "ts-jest"
      },
      verbose: true
    }
    
  8. Add a new file called babel.config.js and populate it with the necessary presets:

    module.exports = {
      presets: [
        ['@babel/preset-env',
          {
            targets: {
              node: 'current'
            }
          }
        ],
        '@babel/preset-typescript',
      ]
    };
    
  9. Finally, run npm i to install any missing dependencies and set up your environment (hopefully) flawlessly.

Answer №5

Setting up Jest in place of Jasmine/Karma for Angular 18

1. Removing Jasmine and Karma. Run:

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

2. Installing Jest Dependencies.

npm install --save-dev jest@latest @types/jest@latest ts-jest@latest jest-preset-angular@latest

Note: These dependencies are specifically for development purposes only.


3. Creating a configuration file jest.config.js

The file should be placed at the project's root directory.

Content of the file:

module.exports = {
  preset: 'jest-preset-angular',
  setupFilesAfterEnv: ['<rootDir>/setup-jest.ts'],
  globalSetup: 'jest-preset-angular/global-setup',
};

4. Creating a test environment file setup-jest.ts

This file must also be located in the project's root directory.

Content of the file:

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

5. Updating the package.json file

Edit the "scripts" property by adding commands to execute tests with Jest.

  "scripts": {
      ...
     //Default content generated by Angular project
      ...
    "test":"jest",
    "test:watch": "jest --watch",
    "test:coverage": "jest --coverage"
  }

This is how it would look (Result):


6. Modifying the tsconfig.spec.json file

Ensure that the file is correctly configured to work with Jest.

Content of the file:

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


7. Testing if the configuration was successful

Run:

npm run test 

If it's a new project (with default Angular content), it should run without any errors:


To display test coverage percentage, run:

npm run test:coverage 

Result:


To run Jest in watch mode:

npm run test:watch 

Find the repository with the example project

https://github.com/joseOlivares/angular-jest

If you find this helpful,

please endorse my skills on Linkedin

 

For more information about Jest, visit https://jestjs.io/docs/testing-frameworks

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The issue with Angular 2's Ng style is that it does not properly remove the old style when there is a change

I am currently experiencing an issue within my project. When assigning an object to ngStyle in a div, the problem arises where ngStyle does not clear the style properties from the previous object when there is a change in the object. It should ideally rem ...

Get rid of the box-shadow that appears on the top side of mat-elevation

I placed a mat-paginator at the bottom of my mat-table which is styled with a mat-elevation-z4 class. However, when I added the mat-elevation-z4 class to the mat-paginator component as well, the upper shadow from the paginator appears to overflow onto the ...

How can you proceed with a loop in Angular even after receiving a 404 response?

I couldn't find a solution on how to handle the 404 response within a loop in Angular, so I'm reaching out for help here. Here's the code snippet I'm working with: for(let order of orders){ this.api.getURL(order.resource_url).then ...

What is preventing me from sorting multiple times?

My current challenge involves sorting an array of data multiple times for different purposes. While I could choose to save the sorted data on the back end, I prefer handling it this way. However, I have encountered a problem where only one sort operation ...

Working with a function in the stylesheet of TypeScript in React Native allows for dynamic styling

When attempting to use variables in my StyleSheet file, I encounter a type error even though the UI works fine. Any suggestions on how to resolve this issue? type buttonStyle = (height: number, width: string, color: string) => ViewStyle; export type St ...

Determine whether a nullable string property contains a specific string using indexOf or includes may result in an expression error

I am facing a challenge where I need to assign a value conditionally to a const. The task involves checking if a nullable string property in an object contains another nullable string property. Depending on the result of this check, I will then assign the ...

Tips for displaying or concealing a div using Angular Js

I have set up two div elements with a dropdown control in one named div1. I am looking to hide div2 until a value is selected in the dropdown. How can I show or hide a div based on ng-change, ensuring that div2 remains hidden until a value is selected? Cod ...

Unable to invoke extension method on parent class in TypeScript

Wondering about classes and extensions in TypeScript? Let's take a look at an example: We have a base class called Report, with another class named Datasheet that extends from Report. An extension has been added to the Report class, and the goal is ...

Symbolic links in a Git repository

While I know there are architectural flaws in this setup (as it's a simple project), I can't shake the feeling that something is not quite right here. The project consists of two main sub-projects residing in the same folder (proj): An Angular ...

Steps to resolve: The term is not callable. The type '{}' does not have any call signatures.ts(2349)

Hello everyone, I am currently encountering a type error in my login file due to my limited familiarity with typescript. The issue arises when attempting to assign the response from the API to the user variable within my handleLogin function, where user re ...

Completing a Promise Chain with the Power of Node, MySQL, and TypeScript

I'm currently utilizing node and typescript. In my setup, there's a controller and a repository. Strangely, I am able to log data everywhere except right after the return from the repository. As a result, the controller doesn't receive any d ...

typescript tips for incorporating nested types in inheritance

I currently have a specific data structure. type Deposit { num1: number; num2: number; } type Nice { num: number; deposit: Deposit; } As of now, I am using the Nice type, but I wish to enhance it by adding more fields to its deposit. Ultima ...

Is it possible to replicate, modify, or recycle a purely HTML and CSS component in Angular?

On my Angular website, I am looking to reuse a component across more than 30 pages. While the majority of the pages have similar CSS, the content inside varies. I know I can simply insert <app-example></app-example> on all the pages, using < ...

What could be causing the dispatch function to not run synchronously within guards during the initial load?

It has come to my attention that in certain scenarios, the execution of reducers is not happening synchronously when using store.dispatch(...) as expected. This behavior seems to be isolated to CanActivate guards and during the initial loading of the appli ...

Troubleshooting a 400 Bad Request Error when calling ValidateClientAuthentication in ASP.NET WebApi, even after using context.Validated()

I am currently facing an issue with my angularjs HTML client connected to a WebApi project. The APIs work fine when tested using POSTMAN or other REST clients. However, when I try to use browsers with my angularjs client, the browsers always initiate prefl ...

Looking for a regular expression to verify if the URL inputted is valid in TypeScript

After conducting thorough research, I discovered that none of the suggested URLs met my criteria, prompting me to raise a new query. Here are my specific requirements: * The URL may or may not include 'http' or 'https' * The URL can co ...

The type 'Promise<any>' cannot be assigned to the type 'Contact[]'

After exhausting all my resources on the internet and StackOverflow, I still couldn't find the right answer. This is my first project in Angular with MongoDB, but I keep encountering this error: "Type 'Promise' is not assignable to type &apo ...

Using SQLite to handle JSON data

I am currently working with Ionic2/Angular2 framework. My aim is to save data on the user's device or browser. While Local Storage seems like an option, I have concerns about its reliability. Although SQLite is a dependable choice, it uses SQL inste ...

Unlock the encrypted information in the blockchain

I've been working on encrypting and decrypting values using Node's built-in crypto module. I found a helpful tutorial that showed me how to encrypt the data, but it didn't provide any sample code for decryption. When I tried using code from ...

Determine characteristics of object given to class constructor (typescript)

My current scenario involves the following code: abstract class A { obj; constructor(obj:{[index:string]:number}) { this.obj = obj; } } class B extends A { constructor() { super({i:0}) } method() { //I wan ...