In Jurassic Park, before every enclosure inspection you need to prepare equipment, and after the inspection you need to clean up. It is exactly the same with tests - setup and teardown functions allow you to prepare and clean up the test environment.
beforeEach runs before each test in a describe block. It is the ideal place for creating fresh test data.1describe('DinosaurEnclosure', () => {
2 let enclosure;
3 let rex;
4
5 beforeEach(() => {
6 // Before each test we create a new enclosure and dinosaur
7 enclosure = createEnclosure('Zone A', 5);
8 rex = createDinosaur('Rex', 'T-Rex', 'carnivore');
9 });
10
11 it('should add dinosaur to enclosure', () => {
12 enclosure.add(rex);
13 expect(enclosure.dinosaurs).toHaveLength(1);
14 expect(enclosure.dinosaurs[0].name).toBe('Rex');
15 });
16
17 it('should start with empty enclosure', () => {
18 // Thanks to beforeEach, enclosure is always fresh!
19 expect(enclosure.dinosaurs).toHaveLength(0);
20 });
21
22 it('should track capacity', () => {
23 enclosure.add(rex);
24 expect(enclosure.remainingCapacity()).toBe(4);
25 });
26});afterEach runs after each test. It serves to clean up after tests - closing connections, resetting state.1describe('SecuritySystem', () => {
2 let securitySystem;
3 let alarmLog;
4
5 beforeEach(() => {
6 securitySystem = new SecuritySystem();
7 alarmLog = [];
8 securitySystem.onAlarm((msg) => alarmLog.push(msg));
9 });
10
11 afterEach(() => {
12 // Reset the security system after each test
13 securitySystem.deactivate();
14 alarmLog = [];
15 console.log('System reset after test');
16 });
17
18 it('should detect breach', () => {
19 securitySystem.simulateBreach('Zone A');
20 expect(alarmLog).toContain('Breach in Zone A');
21 });
22
23 it('should handle multiple alarms', () => {
24 securitySystem.simulateBreach('Zone A');
25 securitySystem.simulateBreach('Zone B');
26 expect(alarmLog).toHaveLength(2);
27 });
28});beforeAll runs once before all tests in a describe, and afterAll once after all. Use them for expensive operations.1describe('DatabaseTests', () => {
2 let database;
3
4 beforeAll(async () => {
5 // Expensive operation - database connection, only once!
6 database = await connectToDatabase();
7 console.log('Database connected');
8 });
9
10 afterAll(async () => {
11 // Close connection after all tests
12 await database.close();
13 console.log('Database disconnected');
14 });
15
16 beforeEach(async () => {
17 // Clear data before each test
18 await database.clear();
19 });
20
21 it('should save dinosaur', async () => {
22 await database.save({ name: 'Rex', species: 'T-Rex' });
23 const dinos = await database.findAll();
24 expect(dinos).toHaveLength(1);
25 });
26
27 it('should find by species', async () => {
28 await database.save({ name: 'Rex', species: 'T-Rex' });
29 await database.save({ name: 'Blue', species: 'Velociraptor' });
30
31 const raptors = await database.findBySpecies('Velociraptor');
32 expect(raptors).toHaveLength(1);
33 expect(raptors[0].name).toBe('Blue');
34 });
35});It is important to understand the order in which Jest executes setup and teardown:
1describe('Execution order', () => {
2 beforeAll(() => console.log('1. beforeAll'));
3 afterAll(() => console.log('6. afterAll'));
4 beforeEach(() => console.log('2. beforeEach'));
5 afterEach(() => console.log('4. afterEach'));
6
7 it('test 1', () => console.log('3. test 1'));
8 it('test 2', () => console.log('3. test 2'));
9});
10
11// Output:
12// 1. beforeAll
13// 2. beforeEach
14// 3. test 1
15// 4. afterEach
16// 2. beforeEach
17// 3. test 2
18// 4. afterEach
19// 6. afterAllSetup and teardown work hierarchically in nested
describe blocks:1describe('Jurassic Park', () => {
2 beforeEach(() => console.log('Setup: Park'));
3
4 describe('Predator Zone', () => {
5 beforeEach(() => console.log('Setup: Predator Zone'));
6
7 it('T-Rex is in the enclosure', () => {
8 console.log('Test: T-Rex');
9 // Setup order: Park -> Predator Zone
10 });
11 });
12
13 describe('Herbivore Zone', () => {
14 beforeEach(() => console.log('Setup: Herbivore Zone'));
15
16 it('Triceratops is in the enclosure', () => {
17 console.log('Test: Triceratops');
18 // Setup order: Park -> Herbivore Zone
19 });
20 });
21});Nested
describe blocks inherit setup from parent blocks. beforeEach from the parent runs before the child's beforeEach.