JavaScript treats values like 0, '', null, undefined, and NaN as falsy, and everything else as truthy. This lesson covers the Jest matchers built specifically around that concept.
toBeTruthy() and toBeFalsy()
.toBeTruthy() passes if the value would evaluate as true in a boolean context (an if statement), and .toBeFalsy() passes for the opposite. These are intentionally loose — they don't check for a specific value, only its "truthy-ness".
Use these when you care about a general true/false-like outcome ("is a user logged in?") rather than a specific value ("is the count exactly 3?"), where a more precise matcher like .toBe() is a better fit.
.toBeNull() passes only for the exact value null, not other falsy values.
.toBeUndefined() passes only for the exact value undefined.
.toBeDefined() is the exact opposite of .toBeUndefined().
Use these when the specific null/undefined distinction actually matters to your logic.
Truthiness Matchers Cheat Sheet
How to check truthy, falsy, null, and undefined values precisely.
Matcher
Passes For
.toBeTruthy()
Any truthy value
.toBeFalsy()
Any falsy value (0, '', null, undefined, NaN, false)
.toBeNull()
Exactly null
.toBeUndefined()
Exactly undefined
.toBeDefined()
Anything except undefined
.not.toBeNull()
Anything except null
Why Precision Matters Between Falsy Values
.toBeFalsy() cannot tell you *which* falsy value you got — 0, '', and null all pass equally. If your function's contract specifically promises to return null (not 0 or an empty string) when nothing is found, .toBeNull() catches regressions that .toBeFalsy() would silently let through.
function findUser(id) {
// bug: returns 0 instead of null when not found
return users.find((u) => u.id === id) ?? 0;
}
expect(findUser(999)).toBeFalsy(); // misleadingly passes
expect(findUser(999)).toBeNull(); // correctly FAILS, exposing the bug
Testing Boolean Flags Directly
For functions that return an actual boolean, prefer .toBe(true)/.toBe(false) over .toBeTruthy()/.toBeFalsy() when you specifically expect a boolean type, not just a truthy/falsy value. This catches bugs where a function accidentally returns something like 1 or '' instead of a real boolean.
Using .toBeTruthy()/.toBeFalsy() when a specific value check like .toBeNull() or .toBe(false) would catch more bugs.
Assuming .toBeFalsy() means the value is false; it also passes for 0, '', null, undefined, and NaN.
Testing a function that should return a strict boolean with .toBeTruthy() instead of .toBe(true).
Forgetting that NaN is falsy, causing .toBeFalsy() to mask a NaN-producing bug.
Key Takeaways
.toBeTruthy()/.toBeFalsy() check general truthy/falsy behavior, not a specific value.
.toBeNull() and .toBeUndefined() check for those exact values precisely.
Prefer precise matchers whenever your function's contract specifies an exact return value.
Boolean-returning functions are better tested with .toBe(true)/.toBe(false).
Pro Tip
If you catch yourself reaching for .toBeTruthy(), pause and ask what exact value you actually expect. There is almost always a more precise matcher available.
You now understand Jest's truthiness matchers and when to use precise checks instead. Next, explore matchers for comparing numbers.