Search code examples
typescriptts-jest

Typescript with Jest - "ReferenceError: beforeAll is not defined"


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"
  },

Solution

  • 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.