The essential Jest and Vitest matchers (toBe, toEqual, toMatch, toContain, toThrow) and how to choose the right assertion for each scenario to write clear, expressive test expectations.
toBe uses Object.is() for strict reference equality (use for primitives). toEqual performs deep comparison (use for objects and arrays). toStrictEqual adds type checking.
Use toBeCloseTo instead of toBe for decimal math to avoid IEEE 754 precision issues. expect(0.1 + 0.2).toBeCloseTo(0.3) passes while toBe fails.
toThrow must receive a function that calls the throwing code, not the result of calling it directly. Can match by error message string, regex, or error class.
expect.any(), expect.stringContaining(), and expect.objectContaining() enable flexible matching inside complex structures with dynamic fields like timestamps.
Matchers are the building blocks of test assertions. Both Jest and Vitest share the same matcher API (Vitest was designed as a drop-in replacement), so learning these matchers applies to both test runners. Choosing the right matcher makes tests more readable and produces better error messages when tests fail.
toBe(value) uses Object.is() for strict equality (similar to ===). Use it for primitives (numbers, strings, booleans) and reference checks. It fails for objects with the same content but different references.
toEqual(value) performs deep equality comparison, recursively checking object properties and array elements. Use it for objects and arrays where you care about the content, not the reference.
expect(2 + 2).toBe(4); // primitive: use toBe
expect({ a: 1 }).toEqual({ a: 1 }); // object: use toEqual
expect({ a: 1 }).not.toBe({ a: 1 }); // different references!toStrictEqual(value) is like toEqual but also checks that objects have the same type (class instance vs plain object) and that there are no undefined properties. Prefer this over toEqual when you want stricter validation.
toBeTruthy(): Passes if the value is truthy (not false, 0, '', null, undefined, NaN)toBeFalsy(): Passes if the value is falsytoBeNull(): Passes only for nulltoBeUndefined(): Passes only for undefinedtoBeDefined(): Passes for any value that is not undefinedUse specific matchers (toBeNull, toBeUndefined) over generic ones (toBeFalsy) for clearer intent and better error messages.
toBeGreaterThan(n) / toBeLessThan(n): Strict comparisontoBeGreaterThanOrEqual(n) / toBeLessThanOrEqual(n): Inclusive comparisontoBeCloseTo(n, digits): Floating-point comparison that avoids precision issues. Use this instead of toBe for decimal math: expect(0.1 + 0.2).toBeCloseTo(0.3)toMatch(pattern) accepts a regex or string. Use it for partial string matching or pattern validation:
expect('hello world').toMatch(/world/);
expect(errorMessage).toMatch('not found');toContain(item): Checks if an array or string contains the item (uses ===)toContainEqual(item): Like toContain but uses deep equality for objects in arraystoHaveLength(n): Checks the .length propertytoHaveProperty(path, value?): Checks nested properties using dot notation or array pathstoMatchObject(subset): Checks that the object contains at least the specified properties (allows extra properties)expect.objectContaining({}): Asymmetric matcher for partial object matching inside other matcherstoThrow(error?) verifies that a function throws. The function must be wrapped in another function:
expect(() => divide(1, 0)).toThrow('Cannot divide by zero');
expect(() => parseJSON('{')).toThrow(SyntaxError);Any matcher can be negated with .not: expect(value).not.toBe(other).
For flexible matching inside complex structures:
expect.any(Constructor): Matches any instance of the constructorexpect.stringContaining(str): Matches strings containing the substringexpect.arrayContaining(arr): Matches arrays containing at least those elementsThese are powerful for testing objects with dynamic fields like timestamps or IDs.
Fun Fact
Jest's matcher API was inspired by Jasmine, which was itself inspired by Ruby's RSpec. Vitest adopted the same API to be a drop-in replacement, meaning you can often switch from Jest to Vitest by just changing the config file without modifying any test code.