Unit Testing — Cheat Sheet

Tag: testing, unit-test, tdd, jest, vitest, mock, clean-code

Livello: intermedio

TL;DR: Verifica isolata delle singole unità logiche del codice per prevenire regressioni e guidare il design.

Concetti chiave

Testa la più piccola unità testabile dell'applicazione in completo isolamento dalle dipendenze esterne.

Segue il pattern AAA: Arrange (preparazione), Act (esecuzione), Assert (verifica del risultato atteso).

Deve rispettare i criteri FIRST: Fast, Independent, Repeatable, Self-validating, Timely.

I test unitari devono essere deterministici e privi di effetti collaterali verso rete, filesystem o database.

Si usano i test double (mock, stub, spy, dummy, fake) per sostituire i collaboratori esterni.

La copertura del codice (code coverage) misura le linee attraversate, non la correttezza logica delle asserzioni.

TDD applica il ciclo Red-Green-Refactor: scrivi il test prima del codice di produzione.

Testare il comportamento osservabile e le interfacce pubbliche anziché i dettagli implementativi interni.

Domande tipiche e risposte pronte

Q: Qual è la differenza sostanziale tra uno Stub e un Mock?R: Uno stub fornisce risposte prefissate alle chiamate senza verificare le interazioni, mentre un mock registra le chiamate e verifica le asserzioni sul comportamento.

Q: Perché evitare di testare metodi o proprietà private?R: Testare i dettagli privati rende il test fragile al refactoring; preferisco testare l'interfaccia pubblica che ne esercita indirettamente la logica.

Q: Come approcci il codice legacy non coperto da test?R: Individuo i punti di giuntura, introduco prima test di caratterizzazione per congelare il comportamento attuale e poi rifattorizzo a piccoli passi.

Insidie e errori comuni

Creare mock eccessivi che riflettono la struttura interna anziché il contratto dell'unità logica.

Inserire logica condizionale o loop all'interno dei test case.

Dipendenza dall'ordine di esecuzione dei test all'interno della suite.

Mancato reset dello stato globale o dei mock tra un test e l'altro.

Assert multipli non correlati che verificano comportamenti distinti nello stesso blocco.

Snippet e comandiTypeScript

```import { describe, it, expect, vi } from 'vitest';

describe('CalculatorService', () => {

it('should apply discount and round total correctly', () => {

// Arrange

const loggerMock = { log: vi.fn() };

const service = new CalculatorService(loggerMock);

// Act

const result = service.calculateTotal(100, 0.1);

// Assert

expect(result).toBe(90);

expect(loggerMock.log).toHaveBeenCalledWith('Calculated: 90');

});

});

```

Da ripassare

[ ] Differenze architetturali tra Mockist e Classicist (London vs Detroit School)

[ ] Configurazione corretta dei fake timers per operazioni asincrone

[x] Principi FIRST e struttura AAA per la leggibilità dei test

[x] Isolamento delle chiamate I/O tramite dependency injection

Jarvis Interviews
Jarvis