3

So I'm trying to have some global variables to use easily in my test files so I researched a lot and managed to make a jest setup file that runs before all my test files to initialize the global variables and this is the setup.ts file

import  app  from'../src/express';
import request from 'supertest';


//Set Express app as global
global.app = request(app);

//TODO: Add global data

It's working fine but the autocomplete isn't working in my test files so after searching for the problem I found out I had to merge my new added variables to NodeJS.Global and ended up doing so in a file called global.d.ts


declare global {
    namespace NodeJS {
     interface Global {
       app: import('supertest').SuperTest<import('supertest').Test>;
     }
   }
 }

but still, nothing is working tried other solutions but none worked.

Note

ts.config

"target": "es2019",
    "moduleResolution": "node",
    "module": "commonjs",
    "lib": ["es2019"],
    "sourceMap": true,
    "outDir": "dist",
    "strict": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "noImplicitThis": true,
    "resolveJsonModule": true,
    "alwaysStrict": true,
    "removeComments": true,
    "noImplicitReturns": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "allowJs": true /* Allow javascript files to be compiled. */,
    "typeRoots": [
      "./types",
      "node_modules/@types",
      
    ] /* List of folders to include type definitions from. */,
    "types": [ "node","jest"],
  },
  "include": ["./src/**/*", "./utils/**/*", "localization", "./tests/**/*"],
  "exclude": ["./seeds/**/*"]

jest.config.ts

/*
 * For a detailed explanation regarding each configuration property and type check, visit:
 * https://jestjs.io/docs/configuration
 */

export default {
  clearMocks: true,
  coverageProvider: "v8",
  coverageDirectory: "coverage",
  collectCoverage: true,
  setupFiles: ["<rootDir>/tests/setup.ts"],
  testMatch: [
    "<rootDir>/tests/**/*.test.ts"
  ],

};

Shahda
  • 57
  • 1
  • 7

2 Answers2

2

If you want to use it like app (instead of global.app), then declare it globally:

declare global {
  const app: import('supertest').SuperTest<import('supertest').Test>;
}
basarat
  • 261,912
  • 58
  • 460
  • 511
2

I had a similar usecase, where I needed a safeSubscribe helper available globally in all my tests.
This function would perform the subscription and then do the unsubscription in a general afterEach hook, executed after any test.

Here is how I achieved that:

// test/setup/safe-subscribe.ts
import { Observable, Subscription } from 'rxjs';

const subscriptions: Subscription[] = [];
const safeSubscribeFn = <T>(source: Observable<T>): T[] => {
  const res: T[] = [];
  const subscription = source.subscribe((value) => {
    res.push(value);
  });
  subscriptions.push(subscription);
  return res;
};

global.safeSubscribe = safeSubscribeFn; // Add helper implementation

global.afterEach(() => {
  while (subscriptions.length > 0) {
    const subscription = subscriptions.pop();
    subscription?.unsubscribe();
  }
});

declare global {
  // See: https://stackoverflow.com/a/68328575/12292636
  var safeSubscribe: typeof safeSubscribeFn;
}
// jest.config.js
module.exports = {
  ...,
  setupFilesAfterEnv: [
    ...,
    './test/setup/safe-subscribe.ts', // Import your setup in jest config
  ],
};
// tsconfig.spec.json
{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "./out-tsc/spec",
    "module": "commonjs",
    "types": ["jest", "node"],
    "resolveJsonModule": true,
    "esModuleInterop": true,
  },
  "files": ["src/polyfills.ts", "test/setup/*.ts"], // Add it there
  "include": ["src/**/*.d.ts", "src/**/*.spec.ts", "test/setup/*.ts"] // And also there
}

Now, it is possible to use the globally-defined safeSubscribe in the tests:

// foo.spec.ts
it('should emit value', () => {
  // Given
  const outputs = safeSubscribe(service.myObservable$); // global import with typescript stuff ✔️
  // When
  actions$.next(action);
  // Then
  expect(outputs).toHaveLength(1);
});
fservantdev
  • 528
  • 8
  • 18