jest: How to teardown after (just) an individual test
Asked Answered
A

2

34

jest provides afterEach, beforeEach, afterAll and beforeAll to complete setup and teardown logic. What I would like to do, is to clear up after one particular test. Consider the following:

describe("a family of tests it makes sense to group together", () => {
    ...
    test("something I want to test", () => {
        // some setup needed for just this test
        global.foo = "bar"
        
        // the test
        expect(myTest()).toBe(true)

        // clear up
        delete global.foo
    }
    ...
}

The problem with the above...

If the test above fails for some reason, then delete global.foo is never run. This means that potentially all of the tests following it will fail. Rather than seeing 1 test fail, I see a whole load of tests fail, which could be confusing.

Potential (non-ideal) solutions

One solution is just to add delete global.foo into my afterEach. It doesn't really need to be run after every test, but it doesn't do any harm either. Another solution would be to put the particular test by itself so that afterEach would only apply to it. But this doesn't seem ideal either - if that test belongs with other tests, it aught to be possible for it to remain with them.

My question:

Is there a way to run teardown logic for just a specific test (without running it inside the actual test). In my particular use-case the first outlined solution is fine, but I can imagine there might be situations where finer grained control is needed. If my teardown method took a long time for example I wouldn't want to repeat it lots, as this would slow down the whole test-suite.

Acquaintance answered 17/7, 2020 at 16:16 Comment(0)
F
22

In many cases tests can share a common afterEach clean-up even if it's needed for one of them, as long as it doesn't affect others.

Otherwise, this is what block structure is responsible for. One or several tests can be grouped with nested describe just to have their own afterEach, etc blocks, and the only downside is that it makes the report less pretty:

describe("a family of tests it makes sense to group together", () => {
    ...
    describe("something I want to test", () => {
        beforeEach(() => {
            global.foo = "bar"
        });
   
        test("something I want to test", () => {
            expect(myTest()).toBe(true)
        }

        afterEach(() => {    
            delete global.foo
        });
    });

beforeEach and afterEach can be desugared to try..finally:

test("something I want to test", () => {
    try {
        global.foo = "bar"
        
        expect(myTest()).toBe(true)
    } finally {
        delete global.foo
    }
})

This also allows for asynchronous tests but requires them to be written with async instead of done.

Foran answered 17/7, 2020 at 16:44 Comment(1)
I found the nested describe method better than try..finally block because when the code in the finally block fails test fails but when the code in the afterEach or afterAll fails test can still pass.Gerita
S
6

I know that this is an old question, but for anyone who stumbles upon this challenge in the future, here's a small library I wrote way back when, called jest-after-this that does just that:

import { afterThis } from 'jest-after-this';

it('should do something that requires a cleanup', () => {
  global.foo = 'something';
  afterThis(() => {
    delete global.foo;
  });

  // ... rest of test here can fail, the cleanup method will run anyways
});

Hope this helps :)

Synder answered 2/10, 2022 at 11:31 Comment(3)
Although the npm page doesn't have a link to the source on GitHub, the npm website allows inspecting the published lib for malware and it LGTM. Kudos @illberoy !Bujumbura
Nice solution! I was also suprised not seeing a GitHub link. Would you be so kind to update the npm page @illBeRoy? For anyone intrested: github.com/illBeRoy/jest-after-thisDiffident
This should be a part of the jest npm package. It's unfortunate that it seems to be falling through the cracks: github.com/jestjs/jest/issues/9305Dusen

© 2022 - 2024 — McMap. All rights reserved.