xtrinch
xtrinch

Reputation: 2291

Running e2e tests with jest @ nestjs

I'm trying to run e2e tests with jest & nestjs and I've run into the weirdest error that doesn't return anything in my google searches (ExpressAdapter is not a constructor):


    $ env-cmd -f .env.test jest --config ./test/jest-e2e.json
     FAIL  test/sensor.e2e-spec.ts (29.498 s)
      SensorController (e2e)
        × /sensors (GET) (15165 ms)

      ● SensorController (e2e) › /sensors (GET)

        Timeout - Async callback was not invoked within the 5000 ms timeout specified by jest.setTimeout.Error: Timeout - Async callback was not invoked within the 5000 ms timeout specified by jest.setTimeout.

          at mapper (../node_modules/jest-jasmine2/build/queueRunner.js:29:45)

      ● SensorController (e2e) › /sensors (GET)

        TypeError: Cannot read property 'getHttpServer' of undefined

          24 |
          25 |   it('/sensors (GET)', () => {
        > 26 |     return request(app.getHttpServer()).get('/sensors').expect(200);
             |                        ^
          27 |   });
          28 |
          29 |   afterAll(async () => {

          at Object.<anonymous> (sensor.e2e-spec.ts:26:24)

    Test Suites: 1 failed, 1 total
    Tests:       1 failed, 1 total
    Snapshots:   0 total
    Time:        29.69 s
    Ran all test suites.

    ReferenceError: You are trying to `import` a file after the Jest environment has been torn down.

          17 |     }).compile();
          18 |
        > 19 |     app = moduleFixture.createNestApplication();
             |                         ^
          20 |
          21 |     await app.init();
          22 |     fixture = await SensorFixture(app);

          at ../node_modules/@nestjs/testing/testing-module.js:25:117
          at Object.loadPackage (../node_modules/@nestjs/common/utils/load-package.util.js:9:27)
          at TestingModule.createHttpAdapter (../node_modules/@nestjs/testing/testing-module.js:25:56)
          at TestingModule.createNestApplication (../node_modules/@nestjs/testing/testing-module.js:13:43)
          at Object.<anonymous> (sensor.e2e-spec.ts:19:25)
    (node:1500) UnhandledPromiseRejectionWarning: TypeError: Caught error after test environment was torn down

    ExpressAdapter is not a constructor
    (node:1500) 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: 2)
    (node:1500) [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.
    Jest did not exit one second after the test run has completed.

    This usually means that there are asynchronous operations that weren't stopped in your tests. Consider running Jest with `--detectOpenHandles` to troubleshoot this issue.
    error Command failed with exit code 1.
    info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

My jest-e2e.json:


    {
      "moduleFileExtensions": ["js", "json", "ts"],
      "rootDir": ".",
      "testEnvironment": "node",
      "testRegex": ".e2e-spec.ts$",
      "transform": {
        "^.+\\.(t|j)s$": "ts-jest"
      },
      "moduleNameMapper": {
        "~(.*)$": "<rootDir>/../src/$1"
      }
    }


jest.config.js:

    module.exports = {
      verbose: true,
      preset: 'ts-jest',
      rootDir: 'src',
      moduleNameMapper: {
        '~(.*)$': '<rootDir>/$1',
      },
      moduleFileExtensions: ['js', 'json', 'ts'],
      moduleDirectories: [
        "node_modules", 
        "src"
      ],
    };

I'm using typeorm and I'm pretty sure my test database config is correct since my unit tests execute without an issue (I'm running them against an actual test database).

ormconfig.js:

module.exports = {
  type: process.env.DB_TYPE,
  host: process.env.DB_HOST,
  port: process.env.DB_PORT,
  username: process.env.DB_USERNAME,
  password: process.env.DB_PASSWORD,
  database: process.env.DB_DATABASE,
  entities: process.env.DB_ENTITIES.split(' '),
  synchronize: process.env.DB_SYNCHRONIZE,
  autoLoadEntities: true,
  logging: process.env.DB_LOGGING,
}

env variables:

DB_TYPE = "postgres"
DB_HOST = "localhost"
DB_PORT = 5432
DB_USERNAME = "postgres"
DB_PASSWORD = "postgres"
DB_DATABASE = "sensor-dashboard-test"
DB_SYNCHRONIZE = true
DB_LOGGING = true
DB_ENTITIES = "**/*.entity{.ts,.js} ../src/modules/**/*.entity{.ts,.js}"

My dependencies:

  "dependencies": {
    "@nestjs/common": "^7.0.0",
    "@nestjs/core": "^7.0.0",
    "@nestjs/platform-express": "^7.0.0",
    "@nestjs/typeorm": "^7.1.0",
    "class-transformer": "^0.2.3",
    "class-validator": "^0.12.2",
    "date-fns": "^2.15.0",
    "env-cmd": "^10.1.0",
    "nestjs-admin": "^0.4.0",
    "nestjs-typeorm-paginate": "^2.1.1",
    "pg": "^8.3.0",
    "postgres": "^1.0.2",
    "reflect-metadata": "^0.1.13",
    "rimraf": "^3.0.2",
    "rxjs": "^6.5.4",
    "typeorm": "^0.2.25",
    "uuid": "^8.2.0"
  },

And the entire e2e test that fails:

import { Test, TestingModule } from '@nestjs/testing';
import { INestApplication } from '@nestjs/common';
import * as request from 'supertest';
import {
  SensorFixtureInterface,
  SensorFixture,
} from '~modules/sensor/sensor.fixture';
import { AppModule } from '~app.module';

describe('SensorController (e2e)', () => {
  let app: INestApplication;
  let fixture: SensorFixtureInterface;

  beforeEach(async () => {
    const moduleFixture: TestingModule = await Test.createTestingModule({
      imports: [AppModule],
    }).compile();

    app = moduleFixture.createNestApplication();

    await app.init();
    fixture = await SensorFixture(app);
  });

  it('/sensors (GET)', () => {
    return request(app.getHttpServer()).get('/sensors').expect(200);
  });

  afterAll(async () => {
    await app.close();
  });
});

app.module.ts:

import { Module } from '@nestjs/common';
import { AppService } from './app.service';
import { SensorModule } from '~/modules/sensor/sensor.module';
import { DefaultAdminModule } from 'nestjs-admin';
import { TypeOrmModule } from '@nestjs/typeorm';
import { MeasurementModule } from '~/modules/measurement/measurement.module';

@Module({
  imports: [
    SensorModule,
    MeasurementModule,
    DefaultAdminModule,
    TypeOrmModule.forRoot(),
  ],
  controllers: [],
  providers: [AppService],
})
export class AppModule {}

Link to the entire project: https://github.com/xtrinch/sensor-dashboard-nestjs-backend

Upvotes: 9

Views: 10743

Answers (1)

user15964382
user15964382

Reputation: 166

I got this same error, and fixed it by passing only ts files (entities) to my typeorm testing environment.

Ex:

module.exports = {
  type: DB_TYPE,
  host: DB_HOST,
  port: DB_PORT,
  username: DB_USERNAME,
  password: DB_PASSWORD,
  database: DB_DATABASE,
  migrations: ['**/migrations/*.{ts,js}'],
  entities: NODE_ENV === 'test' ? ['**/*.entity.{ts}'] : ['**/*.entity.{ts,js}'],
  cli: {
    entitiesDir: 'src/database/entities',
    migrationsDir: 'src/database/migrations',
  },
};

Upvotes: 7

Related Questions