Typescript with Jest - "ReferenceError: beforeAll is not defined"
Asked Answered
U

5

19

So I have a project where I am using:

  • Typescript
  • TypeORM
  • Type-graphql
  • Jest

I had it working just fine until I started writing my tests. The test files are inside of each entity folder. For example:

  Student
  |- Student.ts
  |- Student.test.ts
  |- StudentService.ts

When I run Jest to execute my tests, everything is just fine and works as expected. However, if I run nodemon --exec ts-node src/index.ts I get an error for the first Jest related function I have, whether it is beforeAll(), afterAll(), describe()...

My tsconfig.json is:

{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "lib": ["dom", "es6", "es2017", "esnext.asynciterable"],
    "sourceMap": true,
    "outDir": "./dist",
    "moduleResolution": "node",

    "types": ["jest", "node"],

    "removeComments": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "noImplicitThis": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true
  },
  "include": ["**/*.ts"],
  "exclude": ["node_modules", "**/*.test.ts", "**/*.spec.ts"]
}

My jest.config.js is:

module.exports = {
  preset: "ts-jest",
  testEnvironment: "node",
  roots: ["./src"],
  testMatch: [
    "**/__tests__/**/*.+(ts|tsx|js)",
    "**/?(*.)+(spec|test).+(ts|tsx|js)",
  ],
  transform: {
    "^.+\\.(ts|tsx)$": "ts-jest",
  },
};

From what I can understand, typescript is trying to compile my test files even when they are set to be excluded inside of the tsconfig.

More information that might be useful: I have jest, ts-jest and @types/jest as devdependencies. I have only one tsconfig.json file and one jest.config.js

Any idea on how to fix this?

Update 1

I forgot to post the one of the test files, although I don't think it is related to the issue or is the cause of my problem...

import { createTestConnection } from "../../test/createTestConnection";
import { graphqlCall } from "../../test/graphqlCall";
import { Connection } from "typeorm";

let conn: Connection;

beforeAll(async () => {
  console.log("Test started");

  conn = await createTestConnection(true);
});

afterAll(() => {
  conn.close();
});

const addStudentWithoutGuardian = `
  mutation addStudentWithoutGuardian($studentInput: StudentInput!) {
  addStudent(studentInput: $studentInput) {
    id
  }
}
`;

describe("Student", () => {
  it("create only with basic information", async () => {
    console.log(
      await graphqlCall({
        source: addStudentWithoutGuardian,
        variableValues: {
          studentInput: {
            firstName: "Harry",
            lastName: "Smith",
            dateOfBirth: "1997-01-30",
            pronoun: 0,
            gender: 0,
            phone: "1231231234",
            email: "[email protected]",
            addressLine1: "123 Avenue",
            city: "Toronto",
            state: "Ontario",
            postalCode: "X1X1X1",
            gradeLevel: "grade level",
          },
        },
      })
    );
  });
});

Update 2

Error stack

$ nodemon --exec ts-node src/index.ts
[nodemon] 2.0.7
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: ts,json      
[nodemon] starting `ts-node src/index.ts`   
(node:11716) UnhandledPromiseRejectionWarning: ReferenceError: beforeAll is not defined
    at Object.<anonymous> (G:\Documents\repos\tms\server\src\model\Student\Student.test.ts:7:1)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Module.m._compile (G:\Documents\repos\tms\server\node_modules\ts-node\src\index.ts:1056:23)
    at Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
    at Object.require.extensions.<computed> [as .ts] (G:\Documents\repos\tms\server\node_modules\ts-node\src\index.ts:1059:12)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Module.require (internal/modules/cjs/loader.js:952:19)
    at require (internal/modules/cjs/helpers.js:88:18)
    at G:\Documents\repos\tms\server\src\util\DirectoryExportedClassesLoader.ts:41:22
(Use `node --trace-warnings ...` to show where the warning was created)
(node:11716) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:11716) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
[nodemon] clean exit - waiting for changes before restart

Update 3

My index.ts

import "reflect-metadata";
import { createConnection } from "typeorm";
import express from "express";
import { ApolloServer } from "apollo-server-express";
import cors from "cors";
import { createSchema } from "./utils/createSchema";

(async () => {
  const app = express();

  app.use(
    cors({
      origin: ["http://localhost:3000"],
      credentials: true,
    })
  );

  await createConnection();

  const apolloServer = new ApolloServer({
    schema: await createSchema(),
    context: ({ req, res }) => ({ req, res }),
  });

  apolloServer.applyMiddleware({ app, cors: false });

  app.listen(4000, () => {
    console.log("Express server started");
  });
})();

Update 4

My dependenciesand devDependencies

"dependencies": {
    "apollo-server-express": "^2.19.2",
    "class-validator": "^0.13.1",
    "cors": "^2.8.5",
    "dotenv": "^8.2.0",
    "express": "^4.17.1",
    "faker": "^5.2.0",
    "graphql": "^15.4.0",
    "pg": "^8.5.1",
    "reflect-metadata": "^0.1.13",
    "type-graphql": "^1.1.1",
    "typeorm": "^0.2.30",
    "typeorm-seeding": "^1.6.1"
  },
  "devDependencies": {
    "@types/express": "^4.17.11",
    "@types/faker": "^5.1.6",
    "@types/jest": "^26.0.20",
    "@types/node": "^14.14.21",
    "jest": "^26.6.3",
    "nodemon": "^2.0.7",
    "ts-jest": "^26.5.0",
    "ts-node": "^9.1.1",
    "typescript": "^4.1.3"
  },
Utile answered 5/2, 2021 at 1:20 Comment(9)
Provide more error detail info, like error stack trace.Rodroda
Just added the error stack trace @hoangdv. Thanks.Utile
It look like the index.ts file imports .test.ts file.Rodroda
Initially, that is what I thought or that maybe I was accidentally importing it somewhere else, but I have already triple checked for any unintended imports and everything seems fine. @RodrodaUtile
Also if I simply delete the file, the project starts to run again. I guess that if I were importing the student.test.ts somewhere else I would get some error because the file does not exist anymore...Utile
Check again in your project, have any .js file exist, like Student.test.js. js instead of tsRodroda
Just double-checked and all files are correctly named.Utile
Have any js file in your project? check by file explore (finder) instead of by your ide.Rodroda
The only .js file I have is jest.config.js, when I run yarn ts-jest config:init that is the file it creates. Also, just to be sure I tried renaming it to be a .ts file, but doesn't change anything.Utile
U
3

So I just figured it out... It was really silly...

The ormconfig.json has a path to scan all the entities, like this:

"entities": ["src/model/**/*.ts"],

I had to change to:

"entities": ["src/model/**/!(*.test.ts)"],

This was the reason why some of my test files were being loaded and then throwing errors related to Jest functions not being found.

I found this solution after searching for a way to exclude certain files in a similar way tsconfig.json does, however, TypeORM has no exclude parameter so it has to be done with like above.

Github issue with the suggestion

Thanks for all the help.

Utile answered 5/2, 2021 at 5:49 Comment(1)
I had think about why beforeAll runs in your code)) miss something about it but I wasn't sureWeka
F
68

For anybody who was trying to get a globalSetup to work in Jest and getting ReferenceError: beforeAll is not defined - I'll save you a few hours of hitting your head against the desk:

  1. Define your setup file - jest.setup.ts
  2. Use the setupFilesAfterEnv property. i.e. setupFilesAfterEnv: ['./jest.setup.ts']

Jest globals are not available in setupFiles orglobalSetup

Reference: https://jestjs.io/docs/configuration#setupfilesafterenv-array

Festive answered 13/9, 2021 at 21:37 Comment(4)
This works, however, I get an error saying Your test suite must contain at least one test.Conformist
@Conformist add a test into your empty test file.Festive
the issue with that is that this empty test is run before all the tests. Not particularly effcient.Conformist
@Festive Thanks. Below is my config and it works ``` // The paths to modules that run some code to configure or set up the testing environment before each test setupFiles: [ // '<rootDir>/test/setupFile.js' ], // A list of paths to modules that run some code to configure or set up the testing framework before each test setupFilesAfterEnv: [ '<rootDir>/test/setupFile.js' ], ```Outwork
U
3

So I just figured it out... It was really silly...

The ormconfig.json has a path to scan all the entities, like this:

"entities": ["src/model/**/*.ts"],

I had to change to:

"entities": ["src/model/**/!(*.test.ts)"],

This was the reason why some of my test files were being loaded and then throwing errors related to Jest functions not being found.

I found this solution after searching for a way to exclude certain files in a similar way tsconfig.json does, however, TypeORM has no exclude parameter so it has to be done with like above.

Github issue with the suggestion

Thanks for all the help.

Utile answered 5/2, 2021 at 5:49 Comment(1)
I had think about why beforeAll runs in your code)) miss something about it but I wasn't sureWeka
A
2

Try this as referred jest doc https://jestjs.io/docs/api.

import { expect, jest, test, beforeAll, afterAll } from '@jest/globals';
Athalie answered 9/1, 2024 at 7:3 Comment(0)
W
0

check that package.json has all dependencies:

{
  "name": "ts_test",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "devDependencies": {
    "jest": "^26.6.3",
    "ts-jest": "^26.5.0",
    "ts-node": "^9.1.1",
    "typescript": "^4.1.3"
  }
}

I ran with you configs: yarn jest It works.

 PASS  src/sum.test.ts
  ✓ adds 1 + 2 to equal 3 (4 ms)

  console.log
    Test started

      at src/sum.test.ts:4:11

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        4.023 s
Ran all test suites.
Done in 5.06s.

sum.test.ts

import sum from './sum';

beforeAll(async () => {
  console.log("Test started");
});

test('adds 1 + 2 to equal 3', () => {
  expect(sum(1, 2)).toBe(3);
});

sum.ts

function sum(x:number, y:number):number {
  return x + y;
}

export default sum

run with nodemon

yarn nodemon --exec ts-node src/sum.ts
yarn run v1.22.4
$ /home/.../ts_test/node_modules/.bin/nodemon --exec ts-node src/sum.ts
[nodemon] 2.0.7
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: ts,json
[nodemon] starting `ts-node src/sum.ts`
[nodemon] clean exit - waiting for changes before restart
Weka answered 5/2, 2021 at 3:32 Comment(3)
Hey, so my problem is not running jest, jest runs perfectly fine, but when I try to just run the project using nodemon --exec ts-node src/index.ts I get errors for all the jest related functions such as "beforeAll", "afterAll", "describe" or whichever comes first. I also added my dependencies and devDependencies to the question.Utile
it think that it works too, I appended output to answerWeka
if you want put a part of your project with this bug to github because I may miss somethingWeka
S
0

If, like me, you just wanted beforeAll and afterAll calls from your test files to be recognized without having to add jest types to tsconfig.json, here's how I fixed it:

const { beforeAll, afterAll } = require('@jest/globals');
Stoneham answered 8/9, 2023 at 7:25 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.