51

I am using ts-jest (Jest and TypeScript) and want to configure some global setup for all test suites (initialize test database).

I found that there is globalSetup options in jest configuration:

"jest": {
    "globalSetup": "./jest-config.js"
}

but only .js file can be used for setup. I want to use .ts file because all my code including code for setup in TypeScript.

How can I achieve this?

Dharman
  • 30,962
  • 25
  • 85
  • 135
Aleksei Semidotskii
  • 1,385
  • 1
  • 10
  • 18

4 Answers4

29

I found a solution.

My initial project structure was:

.
|--src
|  |--service.ts
|--tests
|  |--service.test.ts
|--dist
|--tsconfig.json 
|--package.json

Jest configuration in package.json:

"jest": {
  "globals": {
    "ts-jest": {
      "tsconfig": "tsconfig.json"
    }
  },
  "moduleFileExtensions": ["ts","js"],
  "transform": {
    "^.+\\.(ts|tsx)$": "./node_modules/ts-jest/preprocessor.js"
  },
  "testMatch": [
    "**/tests/**/*.test.(ts|js)"
  ],
  "testEnvironment": "node"
}

With this configuration ts-jest perform in memory transpiling of the .ts files. I have outDir option in compilerOptions of my tsconfig.json, but nothing is written in that outDir and because I cann't use transpiled jest-config.js

Then I move tests folder in src and change Jest config. New structure of the project is:

.
|--src
|  |--service.ts
|  |--tests
|     |--service.test.ts
|     |--jest-config.ts
|--dist
|--tsconfig.json 
|--package.json

New Jest config is:

"jest": {
  "globalSetup": "./dist/tests/jest-config.js",
  "moduleFileExtensions": ["ts", "js", "json"],
  "testMatch": [
    "**/dist/**/*.test.js"
  ],
  "testEnvironment": "node"
}

Now I can use jest-config.js for global setup in Jest.

Addition

  • Jest setup file (in my example jest-config.js) must export one async function:

    module.exports = async function() { ... }

  • Before running the tests, you need to compile source .ts files.

Jayant Bhawal
  • 2,044
  • 2
  • 31
  • 32
Aleksei Semidotskii
  • 1,385
  • 1
  • 10
  • 18
18

Global setup is performed before a ts environment is made available, so a workaround is to create the environment manually by requiring ts-node at the beginning of the file.

In your jest configuration (package.json or jest.config.js):

"globalSetup": "./globalSetup.ts"

Then in globalSetup.ts:

require('ts-node/register');

const setup = (): void => {
  // whatever you need to setup globally
};

export default setup;

You can read more about ts-node on github.

remeus
  • 2,256
  • 2
  • 10
  • 19
  • 1
    Amazing My project structure requires me to place those scripts outside src folder, and this trick save me so much headache. one thing to notice, I had to use this form of path in the jest config - "/path/to/globalSetup.ts" – Ofir G Mar 03 '21 at 17:24
  • Can confirm this just worked for me. – andre_b Nov 16 '21 at 21:56
  • 1
    In Jest 28.1 (and probably some versions before it as well) there is a configuration option called `setupFilesAfterEnv`, claiming it runs after the Jest test environment is set up. Could this be the solution? If not, what works differently than expected? https://jestjs.io/docs/configuration#setupfilesafterenv-array – Nils Aug 22 '22 at 08:07
2

For anyone with TS error with @remeus's answer, the following change will do the trick:

require('ts-node').register({
  transpileOnly: true,
});

If you're using absolute imports, use this:

require('tsconfig-paths').register();
glinda93
  • 7,659
  • 5
  • 40
  • 78
0

@glinda93 answer helped me, but I got an error in globalTeardown file.

The solution was to add require('tsconfig-paths').register(); in globalSetup file and:

require('ts-node').register({
  transpileOnly: true,
});

require('tsconfig-paths').register();

in global teardown file.

for some reason, it worked if the ts-node register is only in the teardown file.

RanST
  • 404
  • 2
  • 6
  • 20