Strings are rarely tested with exact equality alone — you often care whether a substring or pattern appears. This lesson covers .toMatch() and practical string-testing techniques.
Matching Strings with toMatch()
.toMatch() checks whether a string contains a substring, or matches a regular expression. Passing a plain string checks for a direct substring match; passing a RegExp allows for flexible pattern matching.
This is more resilient than .toBe() for strings that include dynamic content (like timestamps or generated IDs) where you only care about part of the output.
Pass a plain string to check for a direct substring.
Pass a RegExp literal for flexible pattern matching (case sensitivity, anchors, character classes).
.not.toMatch() asserts the string does not contain the given substring/pattern.
For exact string equality (no partial matching), use .toBe() instead.
String Matchers Cheat Sheet
Common ways to assert on string values in Jest.
Goal
Example
Exact match
expect(str).toBe('Hello')
Contains substring
expect(str).toMatch('World')
Matches pattern
expect(str).toMatch(/^\\d{3}-\\d{4}$/)
Case-insensitive
expect(str).toMatch(/hello/i)
Does not contain
expect(str).not.toMatch('error')
Array of strings contains
expect(list).toContain('apple')
When to Use a Regex vs. a Plain Substring
A plain substring is simplest when you only care that specific text appears anywhere in the string. A regex becomes necessary when you need to check position (anchors like ^ and $), structure (digits, whitespace, repetition), or case-insensitivity.
// Plain substring — good enough here
expect(errorMessage).toMatch('required');
// Regex — needed to check exact structure
expect(phoneNumber).toMatch(/^\(\d{3}\) \d{3}-\d{4}$/);
Testing Strings with Dynamic Content
When output includes a timestamp, UUID, or other non-deterministic value, avoid .toBe() on the whole string. Instead, match the static parts with .toMatch() and, if needed, separately assert on structure using a regex that describes the dynamic portion's shape.
Using .toBe() on strings that contain dynamic values like timestamps or generated IDs, causing brittle tests.
Writing overly complex regexes when a simple substring check would suffice.
Forgetting to escape special regex characters when matching literal punctuation.
Not adding the i flag when case shouldn't matter for the assertion.
Key Takeaways
.toMatch() accepts either a plain substring or a regular expression.
Use regex anchors and character classes when the string's structure matters, not just its content.
Avoid .toBe() for strings containing dynamic or generated content.
.not.toMatch() is useful for asserting an error message or output does not appear.
Pro Tip
When a test needs to check both static and dynamic parts of a string, split the assertion into two .toMatch() calls instead of building one giant, hard-to-read regex.
You now know how to test strings with Jest. Next, learn matchers for testing arrays and objects.