Quiz - Unit tests for lib
A /lib function refundCharge is broken — it resolves false for every charge. This test reports a pass under Vitest 3:
it('refunds a settled charge', async () => { expect(refundCharge(charge)).resolves.toBe(true);});Why does the broken code slip through green?
.resolves assertion builds a promise that the it callback never awaits, so the callback finishes cleanly and the runner records a pass before the rejection lands..resolves only works on functions that throw, so it silently skips any promise that resolves to a boolean.async, which tells Vitest to ignore the assertions inside it.await, the assertion’s rejection happens a tick later in a void — the canonical form is await expect(refundCharge(charge)).resolves.toBe(true). Vitest 4 turns this exact case into a hard failure.A date codec hands back a Temporal.PlainDate. Which assertion actually pins the calendar day the test cares about?
expect(due.toString()).toBe('2026-03-15');expect(due).toEqual(Temporal.PlainDate.from('2026-03-15'));expect(due).toBe(Temporal.PlainDate.from('2026-03-15'));toEqual on a Temporal value compares opaque internal slots, not the day — it can pass by accident or fail on a value that represents the same day. toBe compares references and fails for two distinct objects. Assert on the observable parts: the ISO string, or .year/.month/.day.A test calls vi.useFakeTimers() and vi.setSystemTime(new Date('2026-01-15T12:00:00Z')), then asserts that Temporal.Now.instant() reports that frozen moment. The assertion fails and reads the real wall-clock time. Why?
vi.useFakeTimers() patches Date, setTimeout, and friends, but not Temporal.Now — Temporal’s clock is a separate mechanism the fakes never reach.vi.setSystemTime only takes effect after the first vi.advanceTimersByTime call.beforeEach instead of beforeAll, so they hadn’t taken effect yet.Date, so fake timers sail right past it. That is exactly why domain “now” goes through the clock.now() seam — you swap a module you own instead of fighting over whether Temporal is faked.You want a type test that catches it when someone adds a fourth cancelled member to the InvoiceState discriminated union. Which matcher fails loudly on the widening?
expectTypeOf<InvoiceState>().toEqualTypeOf<Draft | Sent | Paid>();expectTypeOf<InvoiceState>().toExtend<Draft | Sent | Paid>();toEqualTypeOf is bidirectional, so a widened union breaks the “right side is assignable to the left” half and the test goes red. toExtend is one-way assignability — a wider supertype still satisfies “is-a”, so the new case slips through unnoticed.Sort these test-data needs by the tool you’d reach for: a single paid invoice for one test’s assertion, a captured Stripe checkout.session.completed payload for signature verification, and 50 invoices to fill the dev list page. Which mapping is right?
You’re testing that a /lib function returns Result.err with a particular code. Which assertion is the durable one, and why?
expect(result).toMatchObject({ ok: false, error: { code: 'not_found' } });Partial match pins the discriminator and the code — the contract — and stays quiet about userMessage and any field the error grows later.
expect(result).toEqual({ ok: false, error: { code: 'not_found', userMessage: 'Invoice not found.' },});Exhaustive match proves the whole shape, so nothing can drift unnoticed.
toEqual is an exhaustive deep match — it breaks the day someone adds error.traceId, and it forces you to restate userMessage, the localizable wording you should never pin. Assert the machine-readable contract (class and code), not the user-facing prose.Quiz complete
Score by topic