question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Return cleanup functions from beforeAll and beforeEach

See original GitHub issue

🚀 Feature Proposal

It would be a nice addition if the beforeAll() and beforeEach() function could return cleanup functions. This is based on the cleanup function of React.useEffect().

Because one setup may depend on another, the cleanup functions should run in the reverse order of their definition after the afterAll() and afterEach() blocks respectively. I.e. the following test:

afterAll(() => {
  console.log(1);
});

beforeAll(() => {
  console.log(2);

  return () => {
    console.log(3);
  };
});

afterAll(() => {
  console.log(4);
});

beforeAll(() => {
  console.log(5);

  return () => {
    console.log(6);
  };
});

afterAll(() => {
  console.log(7);
});

it('', () => {
  console.log('test');
});

will log:

2
5
test
1
4
7
6
3

Motivation

Currently one needs to store the variables on a higher scope, so the cleanup can be done in a afterAll() or afterEach() block. This works fine, but it’s more work. One needs to declare the variables and possibly explicitly add type definitions. Also returning such cleanup functions keeps related setup and cleanup close together.

Example

Currently:

import { Sequelize } from 'sequelize-typescript';

import { User } from '../models';
import { setupDB } from '../utils';

let db: Sequelize;

beforeAll(async () => {
  db = await setupDB();
});

afterAll(async () =>
  await db.close();
});

it('should create a user', async () => {
  await User.create({ name: 'Me' });
});

With returned cleanup functions.

import { User } from '../models';
import { setupDB } from '../utils';

beforeAll(async () => {
  const db = await setupDB();

  return () => db.close();
});

it('should create a user', async () => {
  await User.create({ name: 'Me' });
});

Variables can still be assigned for use in other setup blocks or tests

import { Sequelize } from 'sequelize-typescript';

import { User } from '../models';
import { setupDB } from '../utils';

let db: Sequelize

beforeAll(async () => {
  db = await setupDB();

  return () => db.close();
});

afterEach(async () => {
  await db.truncate()
});

it('should create a user', async () => {
  await User.create({ name: 'Me' });
});

Pitch

This changes the behaviour of beforeAll() and beforeEach().

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:3
  • Comments:5 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
remcohaszingcommented, Oct 27, 2020

I have given the @jeysal’s some thought. I like this as well, but I don’t like the idea of having to use .current in every test to access the wanted value. This might even be a source of confusion for some users.

Of course one could still the following, even if the hook would return a fixture ref.

let fixture;

aroundEach(() => {
  fixture = render(<Component />);
  return fixture;
}, (ref /* Same as fixture */) => {
  fixture.unmount();
})

I do like the idea of using a new name for the hook, i.e. aroundEach or setupEach.

0reactions
github-actions[bot]commented, May 5, 2022

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Setup and Teardown - Jest
By default, the beforeAll and afterAll blocks apply to every test in a file. You can also group tests together using a describe...
Read more >
Render same component in beforeAll/beforeEvery: testing ...
I have understood that the cleanup function clears the rendered component after each test, so that is good. import React from "react"; import...
Read more >
Globals · Jest
Runs a function before each of the tests in this file runs. If the function returns a promise, Jest waits for that promise...
Read more >
Jasmine: Understanding the Difference between beforeAll and ...
The beforeEach function executes before any spec in the describe block containing it, as well as before any spec contained inside any inner ......
Read more >
Globals · Jest - API Manual
If you want to run some cleanup just once, after all of the tests run, use afterAll instead. beforeAll(fn, timeout). Runs a function...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found