Jest run async function ONCE before all tests
Asked Answered
S

6

87

I want to use jest for my server unit testing (instead of mocha+chai). Is there a way I can run async function before all tests start (init purposes) only once and not for every test file? And also if there's a way of running something after all tests are done?

Sloan answered 26/7, 2017 at 0:53 Comment(0)
G
83

This feature was added in Jest's 22 version, with globalSetup and globalTeardown configurations. Look at this for examples.

package.json (or in jest.config.js)

{
  ...
  "jest": {
    "globalSetup": "./scripts/jestGlobalSetup.js"
  }
}

/scripts/jestGlobalSetup.js

module.exports = async () => {
  console.log('\nhello, this is just before tests start running');
};

OR

export default async () => {
  console.log('\nhello, this is just before tests start running');
};
Generation answered 22/2, 2018 at 15:5 Comment(1)
Unfortunately, you cannot do anything Jest related in that file (except accessing the options), like setting up global mocks, because the global jest object is not available and you cannot import it outside of a test file.Roscoe
M
22

Jest provides beforeAll and afterAll. As with test/it it will wait for a promise to resolve, if the function returns a promise.

beforeAll(() => {
  return new Promise(resolve => {
    // Asynchronous task
    // ...
    resolve();
  });
});

It also supports callback style, if you have some existing test code that uses callbacks, although it's recommended to use promises.

beforeAll(done => {
  // Asynchronous task
  // ...
  done();
});
Morality answered 28/7, 2017 at 14:33 Comment(5)
Jest beforeAll sounds great, especially re: Promises "If the function returns a promise or is a generator, Jest waits for that promise to resolve before running tests." Does Jasmine have the equivalent? It looks like Jasmine does not support Promises, but does support a done callback approach? I'm specifically using Protractor, but the done callback doesn't work for me as described here,Crus
where can I find the docs that state it can use done() in beforeAll? I can only find it waits for promiseMarsh
Good answer, but not satisfying the requested "only once and not for every test file".Nordgren
This answer is wrong, this happens one time per test fileTrochanter
There is no need to return a promise, you can use async/await beforeAll(async () => {})Nitwit
R
9

jest provides options for both global setup and teardown in new versions. You can create files for both setup and teardown exporting an async function and provide that path in jest configurarion like this.

"globalSetup": "setup-file-path",
"globalTeardown": "tear-down-file-path"

You can read about it further here

Regina answered 26/10, 2019 at 21:16 Comment(1)
Downvoted due to not including a link to a source reference.Invert
A
5

If you execute jest tests with npm you can run any node command or any executable before executing other command

"scripts": {
    "test": "node setup.js && jest"
  }

so now you can run this with command

$ npm t
Acree answered 27/7, 2017 at 8:41 Comment(3)
Thanks but I was looking for Jest solution. Like Mocha allows you to put BeforeAll at a global scope I was hoping Jest has something similar.Sloan
While this solution is ok, this wont run in --watch mode. Is there any Jest solution?Phylissphyll
this answer is out of dateDisenfranchise
B
1

It's become very easy when you use beforeAll function outside the describe block and then assign async keyword to it.

Note: I am using jest @27.4.3 version here

code sample

import { getValuesFromAWSSecretManager } from '../../src/libs/secret_manager';
import quickbooksConfigFrom from '../../src/config/quickbooks';

const quickbooksConfig = quickbooksConfigFrom;

// calling the async beforeALL function to get values from AWS Secret Manager
beforeAll(async () => {
  const secretData = await getValuesFromAWSSecretManager();
  quickbooksConfig.clientId = secretData.QUICKBOOKS_CLIENT_ID;
  quickbooksConfig.clientSecret = secretData.QUICKBOOKS_CLIENT_SECRET;
});

describe('Quickbooks config file should be defined', () => {
  test('Quickbooks File should be exist', () => {
    expect(quickbooksConfig).toBeDefined();
  });

  test('Quickbooks File should be exist and having values', () => {
    expect(quickbooksConfig).toBeTruthy();
  });
});

hope it helps and solves your doubts,

and you might need to do it in each file to apply.

you can check jest beforeAll documentation from here

Blackandblue answered 1/2, 2022 at 5:43 Comment(0)
C
0

For next.js it work like this:

  • vitest.config.ts
import { defineConfig } from 'vitest/config'
import react from '@vitejs/plugin-react'
import tsconfigPaths from 'vite-tsconfig-paths'
 
export default defineConfig({
    plugins: [tsconfigPaths(), react()],
    test: {
        environment: 'jsdom',
        // setupFiles: ['/tests/setup-tests.ts'],
        globalSetup: 'test/setup-tests.ts'
    }
})
  • test/setup-tests.ts
// ==== NEXT.JS ====
import { loadEnvConfig } from '@next/env'
loadEnvConfig(process.cwd())

// ==== BOOTSTRAP ====
import { bootstrap } from '@/src/bootstrap'
export default bootstrap
Crosley answered 22/6 at 16:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.