Rules Hub

Coding Rules Library

← Back to all rules
fullstack ruleStack: testing
testingclean-codereliabilityglobalserror-handling

Wrap global mutations in try-finally for safe test cleanup

When modifying global objects (prototypes, window) in a test, use try-finally to guarantee cleanup even upon failure.

PR: Feat/FCK-2200 - Polyfill isWellFormed for Safari slugs #341Created: Dec 7, 2025

Bad example

Old codets
1test('polyfills missing feature', () => {
2 const original = String.prototype.includes;
3
4 // Mutation: we delete a global property to simulate an old browser
5 Reflect.deleteProperty(String.prototype, 'includes');
6
7 // If this assertion fails, the code throws immediately
8 expect('foo'.includes).toBeUndefined();
9
10 // This line is never reached, leaving the global environment broken for future tests
11 String.prototype.includes = original;
12});

Explanation (EN)

If the assertion fails, the execution stops immediately, and the global `String.prototype` is never restored. This causes 'test pollution', where subsequent tests fail mysteriously because the environment remains broken.

Objašnjenje (HR)

Ako tvrdnja (assertion) ne prođe, izvršavanje se odmah prekida i globalni `String.prototype` se nikada ne vraća u prvobitno stanje. To uzrokuje 'zagađenje testova', gdje naredni testovi misteriozno padaju jer je okruženje ostalo pokvareno.

Good example

New codets
1test('polyfills missing feature', () => {
2 const originalDescriptor = Object.getOwnPropertyDescriptor(String.prototype, 'includes');
3 Reflect.deleteProperty(String.prototype, 'includes');
4
5 try {
6 // Even if this fails...
7 expect('foo'.includes).toBeUndefined();
8 } finally {
9 // ...this always runs, restoring the environment
10 if (originalDescriptor) {
11 Object.defineProperty(String.prototype, 'includes', originalDescriptor);
12 }
13 }
14});

Explanation (EN)

Wrapping the critical section in a `try...finally` block ensures that the cleanup code runs regardless of whether the test passes or throws an error. This keeps the test suite isolated and reliable.

Objašnjenje (HR)

Omotavanje kritičnog dijela u `try...finally` blok osigurava da se kod za čišćenje izvrši bez obzira na to prođe li test ili baci grešku. To održava testove izoliranima i pouzdanima.

Notes (EN)

While `beforeEach`/`afterEach` hooks handle common setups, `try...finally` is often cleaner for single-test specific mutations like checking polyfill behavior.

Bilješke (HR)

Iako `beforeEach`/`afterEach` kuke rješavaju uobičajene postavke, `try...finally` je često čišći za mutacije specifične za jedan test, poput provjere ponašanja polyfilla.