Jest · Unit tests that survive refactors
What is the full lifecycle of a Jest test?
Short answer
Jest registers the file, runs outer then inner beforeEach hooks, executes the test, then runs inner then outer afterEach hooks. beforeAll and afterAll wrap the whole describe block, not a single test.
Understanding the lifecycle prevents surprises around shared state. Registration happens first: the whole file is evaluated, so every describe callback runs and every hook is recorded before any test executes. Only then does Jest run the tests in declaration order within a file.
beforeAll(() => console.log("1 file setup"));
describe("group", () => {
beforeAll(() => console.log("2 group setup"));
beforeEach(() => console.log("3 group before"));
afterEach(() => console.log("5 group after"));
afterAll(() => console.log("7 group teardown"));
test("first", () => console.log("4 test one"));
test("second", () => console.log("6 test two"));
});Execution order per test
- All beforeEach hooks from the outermost block to the innermost
- The test body, including awaited promises
- All afterEach hooks from the innermost block to the outermost
- afterAll once per describe, after its last test
beforeAll is useful for a database connection or a server that is expensive to start. It is dangerous for mutable state because every test shares the same instance. If a test mutates it, later tests can fail depending on order, which is exactly the kind of coupling isolation should prevent.
Follow-ups you should expect
Interviewers use these to check whether the first answer was understanding or memorisation.
- 1Does a failing beforeEach still run afterEach?
- 2Why is beforeAll risky for mutable state?
- 3When are describe callbacks evaluated relative to tests?
- 4What happens to a block when beforeAll throws?
Say it in the interview
Jest collects the file first, so all describe callbacks and hook registrations run before any test. Then for each test it runs beforeEach from outer to inner, the test, and afterEach from inner to outer. beforeAll and afterAll run once around the block. I use beforeAll only for expensive, read-only setup, because sharing mutable state creates order-dependent tests.
Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.
Related questions
Reading is step one
Now say it out loud.
Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live Jest mock interview and get scored feedback on depth, clarity and confidence.