Rules Hub
Coding Rules Library
Rule priority, scope & exceptions
Use this to align rules with the senior-level structure (P0/P1/P2, scope, exceptions/tradeoffs).
Assert on the mock itself, not on hand-rolled capture arrays
Make assertions directly on a spy/mock's calls instead of pushing observed values into a module-level array and asserting on that.
Bad example
| 1 | const capturedAuth: (string | null)[] = []; |
| 2 |
|
| 3 | function handler() { |
| 4 | return http.post(URL, async ({ request }) => { |
| 5 | capturedAuth.push(request.headers.get('Authorization')); |
| 6 | return HttpResponse.json({}); |
| 7 | }); |
| 8 | } |
| 9 |
|
| 10 | test('signs the request', async () => { |
| 11 | await run(); |
| 12 | expect(capturedAuth).toHaveLength(1); |
| 13 | expect(capturedAuth[0]).toMatch(/^HMAC /); |
| 14 | }); |
Explanation (EN)
A module-level array plus reset bookkeeping is extra plumbing that drifts away from what the test is actually checking, and failures point at the array index rather than the request.
Objašnjenje (HR)
Polje na razini modula uz resetiranje stanja je dodatna instalacija koja se udaljava od onoga sto test stvarno provjerava, a greske pokazuju na indeks polja umjesto na sam zahtjev.
Good example
| 1 | const handler = vi.fn((req: Request) => HttpResponse.json({})); |
| 2 | server.use(http.post(URL, ({ request }) => handler(request))); |
| 3 |
|
| 4 | test('signs the request', async () => { |
| 5 | await run(); |
| 6 | expect(handler).toHaveBeenCalledOnce(); |
| 7 | expect(handler.mock.calls[0][0].headers.get('Authorization')).toMatch(/^HMAC /); |
| 8 | }); |
Explanation (EN)
The spy records calls and arguments for you; asserting on `handler.mock.calls` keeps the test close to intent and gives failures that name the mock directly.
Objašnjenje (HR)
Spy sam biljezi pozive i argumente; provjera nad `handler.mock.calls` drzi test blizu namjere i daje greske koje izravno imenuju mock.