Jest Matchers
Jest matchers let tests express expected behavior in readable assertions. Common examples include `toBe`, `toEqual`, `toHaveBeenCalled`, and `toBeInTheDocument`.
A matcher is a method used with Jest's `expect` API to check an actual value against an expected condition. A basic assertion looks like `expect(actual).toBe(expected)`.
`toBe` checks strict identity using JavaScript's `Object.is` semantics, so it is appropriate for primitives and cases where the exact reference matters. For objects and arrays, `toEqual` performs a recursive value comparison and is usually the better choice when you care about structure and contents.
Matchers also cover behavior. For example, `toHaveBeenCalled` verifies that a mock function was invoked, while `toHaveBeenCalledWith` additionally checks the arguments used. Jest provides many specialized matchers for strings, arrays, numbers, exceptions, and other common testing needs.
In React tests, `toBeInTheDocument` is commonly supplied by `@testing-library/jest-dom`. It checks whether a queried DOM element is currently present in the document, making assertions about rendered UI more expressive.
Key points
- `expect(value).toBe(expected)` checks strict identity.
- `toEqual` compares objects and arrays by recursively comparing their contents.
- `toHaveBeenCalled` checks whether a mock function was invoked.
- `toBeInTheDocument` is provided by `@testing-library/jest-dom`, not Jest core.
- Choose the matcher that expresses the behavior you actually want to verify.
Interview questions
What is a Jest matcher?
A matcher is an assertion method used with `expect` to describe what a test result should satisfy. For example, `toBe` checks a value using `Object.is`, while `toEqual` compares nested values. Matchers make test failures more specific and readable.
What is the difference between `toBe` and `toEqual`?
`toBe` uses `Object.is`, so two separately created objects are not equal even if they contain the same properties. `toEqual` recursively compares the contents of objects and arrays. Therefore, use `toBe` for primitive values or intentional reference identity, and `toEqual` for structural comparisons.
How would you test that a callback was called with a particular argument?
Create a Jest mock with `jest.fn()`, invoke the code under test, and use `toHaveBeenCalledWith` on the mock. For example, `expect(callback).toHaveBeenCalledWith('save')` verifies that a call occurred with that argument. This tests observable interaction without requiring the callback's implementation.
What is `toBeInTheDocument`, and where does it come from?
`toBeInTheDocument` is a DOM-specific matcher commonly used with React Testing Library. It is provided by `@testing-library/jest-dom`, which extends Jest's assertion capabilities with DOM-focused matchers. A typical test can query an element and then assert `expect(element).toBeInTheDocument()`.
How should you choose between a generic matcher and a specialized matcher?
Prefer the matcher that most directly describes the behavior being tested. For example, use `toHaveTextContent` for an element's text rather than comparing a larger DOM representation. Specialized matchers usually produce clearer failure messages and make the test's intent easier to understand.