How to Setup Jest on Typescript Monorepo Projects
Tags: testing, typescript, tutorial, javascript
Published: 2024-06-12 14:38:30


![Testing GIF](https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExYjJrMmE5YmdobTYxYTIxeDZsZmZ5Z3dseWVkaWhyYXd0MTF4eXFmMSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/IedrijvVSFIASnhmuX/giphy.gif)

## TL;DR

When I started making open source libraries, I didn't know much about unit testing in terms of writing the tests, and setting up the environment. There was a strong voice that told me to write unit tests for my open source libraries because if one day it gets big (hopefully) it wouldn't be efficient to test every functionality manually.

Acknowledging the benefits of unit testing, I jumped right in to the one and only [Jest](https://jestjs.io/). Honestly it overwhelms me a little bit too much when I read the docs and there are a lot of things going on in there. But I didn't lose spirit by just reading a docs, otherwise I wouldn't call myself a learner 😅

## The challenges

Because it was the first time I'm learning unit testing using Jest, I'm confused on how to set things up and running in my project. Most of my projects are using typescript + monorepo structure and it requires a specific config to make it running. Without further a do, let's dive right into it.

## Setting up

In this section, we'll go through the steps on how to configure Jest in Typescript Monorepo project so please follow along and read the steps carefully.

### Installation

First of all, we have to install a few packages as devDependencies especially if we are using typescript, there are extra packages that we must install.

```bash
$ npm i -D jest @types/jest ts-jest ts-node typescript
```

- **jest:** Is the tool for writing unit tests and run the tests
- **@types/jest:** Contains type definitions for jest
- **ts-jest:** A Jest transformer that allows us to use Jest for testing TypeScript code.
- **ts-node:** Allows us to run TypeScript code directly in Node.js without needing to precompile it to JavaScript
- **typescript:** You know what it is

After installing those packages, you can check your `package.json` to see if they are listed in `devDependencies`.

### Jest config

Let's create a `jest.config.ts` in the root of our project and write this
```ts
import type { Config } from "@jest/types";

const config: Config.InitialOptions = {
  verbose: true,
  preset: "ts-jest",
  testEnvironment: "node",
  transform: {
    "^.+\\.(ts|tsx)$": "ts-jest",
  },
  projects: [
    {
      testPathIgnorePatterns: ["<rootDir>/node_modules/"],
      preset: "ts-jest",
      displayName: "my-package",
      testMatch: ["<rootDir>/packages/my-package/__tests__/**/*.spec.ts"],
    }
  ],
};
export default config;
```
Here is the explanation for each
- **verbose:** To show a verbose version of test reports.
- **preset:** A pre-configured set of settings and configurations for Jest.
- **testEnvironment:** The test environment that will be used for testing.
- **transform:** Specifies how different types of files should be processed before running the tests
- **projects:** Allows us to define multiple sets of configurations within a single Jest setup.
- **testPathIgnorePatterns:** An array of regular expression patterns that Jest uses to ignore test files
- **displayName:** A name to identify our project like an alias.
- **testMatch:** Specify the glob patterns that Jest uses to detect test files.

The configuration above assumes that your project structure look like this.

```
| - - packages
| - - - my-package
| - - - - __tests__
| - - - - - test.spec.ts
| - tsconfig.base.json
```

Inside you root `package.json`, you can create a script to run the test on a specific project.

```json
"script":{
  "test:my-package": "jest --selectProjects=my-package"
}
```

### Writing tests

Now assuming that you have followed the configurations above, it's time for us to create our first test case. Inside the `__tests__` folder, create a file named `test.spec.ts` and write a dummy test to see if the configurations work perfectly.

```ts
describe("Test config", () => {
  it("counts correctly", ()=>{
    expect(1 + 1).toBe(2);
  })
})
```

After writing the sample test, make sure you are in root directory and run the test script.

```bash
npm run test:my-package
```

## Conclusion

Unit testing using Jest is fun but can overwhelm new learners especially when configuring the Jest itself in order for it to work properly. The complexity even increases when we use different architecture such as monorepo. In spite of the complexity that Jest introduces, Jest is still a powerful testing tool that is used by many developers to test their projects, so it's worth it to learn Jest :).

~ Dadah 👋