Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use TypeScript in a Custom Test Environment file in Jest?

I need to enable some global variables to be reachable for my test so I am setting up a Custom Environment to be used in the testEnvironment option in my jest.config.json to achieve that.

For our project we have a TypeScript file that we use for setupFilesAfterEnv option and that works just fine, however the testEnvironment seems to support only ES5. Is there any way to use TypeScript in such option?

I successfully created a Custom Jest Environment using ES5 syntax, however since we are injecting global variables I need TypeScript to also declare a global namespace see: https://stackoverflow.com/a/42304473/4655076.

{
  ///...
  setupFilesAfterEnv: ['<rootDir>/test/setup.ts'], // This works with ts
  testEnvironment: '<rootDir>/test/customJestEnvironment.ts', // This doesn't work with ts
}
like image 705
Andres C. Viesca Avatar asked Sep 30 '19 07:09

Andres C. Viesca


People also ask

Can you test TypeScript with Jest?

Jest supports TypeScript, via Babel. First, make sure you followed the instructions on using Babel above. Next, install the @babel/preset-typescript : npm.

Does Jest use TypeScript?

Jest is a simple, lightweight testing framework that provides a variety of testing capabilities to JavaScript and TypeScript projects. It provides functionality like assertions, mocking, spies, running tests in parallel, prioritizing failed tests, and coverage analysis.

Does Jest need TS node?

When you run jest with a jest. config. ts file it will use ts-node to compile that file, then it will pass it to ts-jest which will compile your tests, then it will pass those . js tests to jest to run it.


2 Answers

You might find this helpful: Configure Jest global tests setup with .ts file (TypeScript)

But basically you can only pass in compiled JS files as environments.

You can do what that article suggests. But it didn't work for me out of the box. So I manually compile my env.

i.e.

in package.json

"test": "tsc --lib es6 --target es6 --skipLibCheck -m commonjs --esModuleInterop true path/to/env.ts && 
jest --config=jest.config.js",

And in jest.config.js

{
  testEnvironment: '<rootDir>/path/to/env.js', // Note JS extension.
}
like image 85
McTrafik Avatar answered Oct 23 '22 22:10

McTrafik


I solved this by using ts-node and the following command:

node -r ts-node/register ./node_modules/jest/bin/jest.js

This essentially compiles the typescript on-the-fly, so that jest receives the emitted javascript, without the need of actually compiling your typescript sources to js.

You will need to enable esModuleInterop TS compiler option for this to work properly.

TestEnvironment.ts


import NodeEnvironment from 'jest-environment-node';
import type {Config} from '@jest/types';

class TestEnvironment extends NodeEnvironment {
    
    constructor(config: Config.ProjectConfig) {
        super(config);
        // this.testPath = context.testPath;
        // this.docblockPragmas = context.docblockPragmas;
    }

    public async setup(): Promise<void> {
        await super.setup();

        console.log('SETTING UP...');
        // await someSetupTasks(this.testPath);
        // this.global.someGlobalObject = createGlobalObject();
    
        // // Will trigger if docblock contains @my-custom-pragma my-pragma-value
        // if (this.docblockPragmas['my-custom-pragma'] === 'my-pragma-value') {
        //   // ...
        // }
    }

    public async teardown(): Promise<void> {
        await super.teardown();
        console.log('TEARING DOWN!');
        // this.global.someGlobalObject = destroyGlobalObject();
        // await someTeardownTasks();
        
    }
}

export default TestEnvironment;

This solution however, will break globalSetup -- if you use jest-ts.

like image 27
Norman Breau Avatar answered Oct 23 '22 23:10

Norman Breau