Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create Jest Custom Environment with Typescript?

I am trying to create an extension off jest-node-environment as a CustomTestEnvironment but am getting the following error when trying to run jest

● Test suite failed to run

    ~/git/my-application/tests/environment/custom-test-environment.ts:1
    import NodeEnvironment from 'jest-environment-node';
    ^^^^^^

    SyntaxError: Cannot use import statement outside a module

      at runTestInternal (../node_modules/jest-runner/build/runTest.js:226:5)

I believe this error means it doesn't recognize this as a typescript file, and hasn't transpiled it. ( I am using the latest version of jest 26.0.1)

Based on discussions in the jest github, the PR to make this work was slated for Jest 26 but was pulled from Jest 26 and is (hopefully) going to be in Jest 27. https://github.com/facebook/jest/pull/8751

That being said, I've seen samples of people doing it this way online but for me I'm not having any luck following their lead.

import NodeEnvironment from "jest-environment-node";
import {LocalObject} from "./object/local-object.helper";

export class CustomTestEnvironment extends NodeEnvironment {

    public async setup(): Promise<void> {
        await super.setup();
        this.global.localObject = LocalObject.init()
    }

    public async teardown(): Promise<void> {
        LocalObject.teardown(this.global.localObject)
        await super.teardown();
    }
}

The LocalObject is just a thin wrapper around a test utility which has a complex startup and teardown and which I want to provide to tests to be able to publish test data and kick off the component test.

If I change the imports to be require -

const NodeEnvironment = require("jest-environment-node");
const {LocalObject} =  require("./object/local-object.helper");

Then I get this error instead -

SyntaxError: Unexpected token 'export'

If I move the export into an module.exports then I get the following error

public async setup(): Promise<void> {
       ^^^^^              

SyntaxError: Unexpected token 'async'

Seems to me like it's not treating this file as typescript.

Is there any workaround to be able to use this as a typescript file? The LocalObject is written in typescript, so I believe that I need this to be typescript to work right with that one, and it is important that LocalObject file remains typescript for test files to use it correctly.

Alternative question: Can I do the same kind of setup/teardown logic in the setupFilesAfterEnv I only saw that they were run before, but not after tests. Thanks.

like image 995
GoldFlsh Avatar asked May 23 '20 15:05

GoldFlsh


People also ask

What is Jest environment Jsdom?

jsdom is a pure JavaScript implementation of the DOM and browser APIs that runs in node. If you're not using Jest and you would like to run your tests in Node, then you must install jsdom yourself. There's also a package called global-jsdom which can be used to setup the global environment to simulate the browser APIs.

What is Jest config JS?

The jest. config. js file is used for configuring Jest, the JavaScript testing library used for writing unit and integration tests in Pup. The modulePaths property tells Jest where it can resolve NPM modules used inside of the code you're testing.

How to test a jest test in typescript?

Testing with jest in TypeScript 1 Create a new project. First, we need a project to be able to write test cases at all. ... 2 Add some functions. Now its time to create a file named calc.ts in the src folder and write a simple function named add. 3 Build the project. ... 4 Configure Jest. ... 5 Conclusion. ...

What is @types/jest and @Babel/preset-typescript?

@types/jest is types library that provides typing and intellisence for global jest keywords such as describe and it in our test file. These makes type safety more robust for type files and provides better IDE support. @babel/preset-typescript transpiles tests written in TypeScript to JavaScript, so Jest can understand them.

What is @types/jest used for?

understand the TypeScript setup before proceeding with this guide. @types/jest is types library that provides typing and intellisence for global jest keywords such as describe and it in our test file. These makes type safety more robust for type files and provides better IDE support.

How do I install typescript in Node JS?

Next, we install TypeScript as a development dependency with the following command: To use the TypeScript compiler locally from the project, we can use the tool npx, which is installed with Node.js beside npm. The TypeScript compiler can help us to create a tsconfig.json from a template with the following command:


1 Answers

UPDATE: Jest 27 is now released and now supports this. If you are using an older version of Jest, update to Jest 27 to be able to use CustomEnvironment as typescript https://jestjs.io/blog/2021/05/25/jest-27#features-coming-with-breaking-changes

Modules used in the following configuration options are now transformed like the rest of your code, which may be breaking if you relied on them being loaded as-is:

  • testEnvironment
  • runner
  • testRunner
  • snapshotResolver

Alternatively, you can continue to use the workaround below for prior versions.


This isn't supported in Jest 26 and is slated to be in Jest 27 https://github.com/facebook/jest/pull/8751#issuecomment-699049851

For now the solution is to use setupFilesAfterEnv files in my jest.config https://jestjs.io/docs/en/configuration#setupfilesafterenv-array.

From there I could put all my my setup/teardown in beforeAll() and afterAll() blocks. This was effectively equivalent to using the Node Environment and the setupFilesAfterEnv files is compatible with typescript.

//jest.setup.ts
import {LocalObject} from "./object/local-object.helper";

let localObject: LocalObject;

beforeAll(async () => {
  //Start my environment or seed data to DB or whatever
  localObject = await LocalObject.init()
}


afterAll(async () => {
  //teardown or clean things started in setup my environment
  await localObject.teardown()
}
like image 93
GoldFlsh Avatar answered Oct 27 '22 17:10

GoldFlsh