Arrays and objects need their own set of matchers because you often care about containment, length, or a subset of properties rather than exact full equality. This lesson covers the most useful ones.
toContain() and toHaveLength()
.toContain() checks whether an array (or string, or any iterable) includes a specific primitive item. .toContainEqual() does the same but with deep equality, useful for arrays of objects. .toHaveLength() checks an array's (or string's) length property directly.
These matchers avoid manually calling .includes() or checking .length yourself, and they produce much clearer failure output when something doesn't match.
.toHaveProperty(path, value?) checks a (possibly nested, dot-separated) property exists, optionally with a specific value.
.toMatchObject(subset) passes if the received object contains at least the given properties — extra properties are ignored.
Both matchers are ideal for testing large API responses where you only care about a few fields.
Use .toEqual() instead when you want to assert on the *entire* object, not a subset.
Array and Object Matchers Cheat Sheet
The matchers most often used for arrays and objects.
Matcher
Checks
.toContain(item)
Array/iterable includes a primitive item
.toContainEqual(item)
Array includes an item, compared deeply
.toHaveLength(n)
Array or string has exactly n elements/characters
.toHaveProperty(path, val?)
Object has a (nested) property, optionally with a value
.toMatchObject(subset)
Object contains at least these properties
.toEqual(arrayOrObject)
Full deep equality
.arrayContaining([...])
Asymmetric matcher: array contains these items
.objectContaining({...})
Asymmetric matcher: object contains these properties
Asymmetric Matchers Inside toEqual()
expect.arrayContaining() and expect.objectContaining() can be nested inside .toEqual() to partially match part of a structure while still checking the rest exactly. This is useful when most of an object needs an exact check, but one field (like a generated timestamp) should be ignored or loosely matched.
Any fields not listed (like an auto-generated id or createdAt) are ignored by the partial matchers.
Checking Deeply Nested Properties
.toHaveProperty() accepts a dot-separated path string (or an array of keys) to reach deeply nested values without manually chaining property access and risking a TypeError if an intermediate value is missing.
When testing an API response with a generated id or createdAt timestamp, reach for .toMatchObject() or expect.objectContaining() instead of stripping those fields out manually before comparing.
You now know how to test arrays and objects thoroughly. Next, learn how beforeEach() and afterEach() manage setup and teardown around your tests.