Jest & Vitest Fundamentals
Chapter 1 established why and what to test. This chapter is the how — the test runner mechanics that every later chapter builds on, kept deliberately DOM-free for now so the focus stays on the runner itself.
Anatomy of a Test File
describe groups related tests under a label. it (or test — the two are interchangeable) defines one individual test case. expect(...) wraps a value so a matcher like .toBe(...) can assert something about it.
Common Matchers
The toBe vs. toEqual distinction trips up almost everyone early on — covered concretely below.
Setup and Teardown
beforeEach/afterEach run before or after every single test; beforeAll/afterAll run once for the whole describe block. Resetting shared state before each test keeps tests isolated — one test's leftover state should never affect another, a concern that becomes far more important once mocking enters the picture.
Basic Mocking with jest.fn() / vi.fn()
A quick preview of Chapter 6's deeper territory — here, just the raw mechanic: a mock function records how it was called, without needing any real implementation behind it.
Vitest: Jest's Vite-Native Sibling
Vitest was built specifically for Vite-based projects — faster, native ESM, no separate Babel/webpack transform step — and deliberately copied Jest's API almost one-to-one. describe, it, and expect work identically; the one real naming difference in the basics is jest.fn() becoming vi.fn(). This course uses Jest's naming by convention (it remains the more common baseline), but everything transfers directly to Vitest with that single substitution.
| Piece | Jest | Vitest |
|---|---|---|
| Grouping / test case / assertion | describe / it / expect | Identical |
| Mock function | jest.fn() | vi.fn() |
| Config file | jest.config.js | vite.config.ts (test block) |
beforeEach / afterEach
Runs before/after every individual test in the block — the default choice for resetting shared state.
beforeAll / afterAll
Runs once for the entire describe block — for expensive setup that's safe to share across tests.
jest --watch and plain vitest (which watches by default) re-run only the tests affected by your latest change, instantly. This is what makes Chapter 1's "unit tests are fast" point actually pleasant in practice — write a small change, glance at the terminal, know within a second whether it broke anything.
expect([1, 2, 3]).toBe([1, 2, 3]) fails — even though the arrays "look the same." toBe checks reference identity (are these the exact same object in memory), and two separately-created arrays never share a reference. Use toEqual for comparing the contents of objects and arrays; reserve toBe for primitives (numbers, strings, booleans) where reference and value are the same thing.
Coding Challenges
Write a describe/it test file for a function multiply(a, b), covering a positive-number case and a case multiplying by zero.
📄 View solutionWrite a test using beforeEach to reset an array-based "cart" to empty before each test, then verify that adding one item results in a cart of length 1 — proving the reset actually runs between tests, not just once.
📄 View solutionWrite a test using jest.fn() to verify that a function processItems(items, callback) calls its callback once per item, with each item as the argument — using toHaveBeenCalledTimes and toHaveBeenCalledWith.
📄 View solutionChapter 2 Quick Reference
- describe(name, fn) — groups related tests; it/test(name, fn) — one test case
- expect(value).matcher(...) — toBe (strict/reference equality), toEqual (deep equality), toBeTruthy/toBeFalsy, toContain, toThrow
- beforeEach/afterEach — run per test; beforeAll/afterAll — run once per describe block
- jest.fn() / vi.fn() — a mock function; toHaveBeenCalled/toHaveBeenCalledWith/toHaveBeenCalledTimes inspect its calls
- Vitest — Jest's Vite-native sibling; near-identical API, jest.fn() → vi.fn() is the main naming change
- toBe checks reference identity; use toEqual for objects/arrays, or a confusing failure is guaranteed
- Watch mode (default in Vitest, `--watch` in Jest) is the everyday workflow, not an optional extra
- Next chapter: The Testing Library Philosophy — testing like a user, not like the implementation