Truthiness Matchers in Jest
JavaScript distinguishes between a value being null, undefined, or simply falsy in a boolean context, and Jest gives you a dedicated matcher for each distinction: toBeNull matches only null, toBeUndefined matches only undefined, toBeDefined is the inverse of toBeUndefined, and toBeTruthy/toBeFalsy evaluate a value the same way an if statement would. Reaching for the most specific matcher available makes a failing test's error message far more useful than a generic toBeTruthy failure would be.
Cricket analogy: It's like an umpire distinguishing between 'no delivery bowled yet' (undefined), 'delivery ruled a no-ball' (null-like invalid outcome), and simply 'not a boundary' (falsy); each status tells a different story about what happened.
test('truthiness matchers distinguish precise states', () => {
let user;
expect(user).toBeUndefined();
user = null;
expect(user).toBeNull();
expect(user).not.toBeDefined();
const items = [];
expect(items.length).toBeFalsy(); // 0 is falsy
expect(items).toBeTruthy(); // an empty array object is truthy
});Number Matchers
For numeric assertions Jest offers toBeGreaterThan, toBeGreaterThanOrEqual, toBeLessThan, and toBeLessThanOrEqual, which map directly onto their mathematical comparison operators. For floating-point results, exact equality is unreliable because operations like 0.1 + 0.2 do not produce exactly 0.3 due to how IEEE 754 doubles represent decimals; toBeCloseTo compares two numbers within a configurable number of decimal digits (2 by default) instead of demanding bit-for-bit equality.
Cricket analogy: toBeCloseTo is like judging a bowler's yorker as accurate if it lands within a few centimeters of the base of the stumps, rather than demanding it hit the exact millimeter, because minor variation is expected in every real delivery.
0.1 + 0.2 === 0.3 evaluates to false in JavaScript because both operands are stored as binary floating-point approximations. expect(0.1 + 0.2).toBeCloseTo(0.3) passes because it checks the difference is smaller than 0.5 * 10^-2 by default.
Choosing the Right Matcher for the Situation
A common source of flaky or misleading tests is defaulting to toBeTruthy or toBeFalsy when a more specific matcher exists. For example, asserting a deleted record is toBeFalsy would also pass if the record were 0, an empty string, or NaN, none of which necessarily mean 'deleted' in your domain. Preferring toBeNull, toBeUndefined, or an explicit toBe(false) documents exactly what the code is expected to produce and makes failures easier to diagnose.
Cricket analogy: It's like a scorer writing 'not out' in the general sense instead of specifying 'retired hurt' versus 'given not out on review'; the vague label technically isn't wrong but hides which specific situation actually occurred.
Be careful with toBeFalsy and toBeTruthy in numeric contexts: 0, NaN, and '' are all falsy but mean very different things. Prefer toBe(0), toBeNaN(), or toBe('') when the exact value matters to your assertion.
- toBeNull matches only null; toBeUndefined matches only undefined; they are not interchangeable.
- toBeDefined asserts a value is anything other than undefined.
- toBeTruthy and toBeFalsy mirror JavaScript's boolean coercion rules used by if statements.
- toBeGreaterThan, toBeLessThan, and their OrEqual variants compare numbers directly.
- toBeCloseTo avoids floating-point precision issues like 0.1 + 0.2 !== 0.3.
- Prefer the most specific matcher available to produce clearer failure messages.
- 0, '', and NaN are all falsy but represent different bugs if misused with toBeFalsy.
Practice what you learned
1. What is the key difference between toBeNull and toBeUndefined?
2. Why does expect(0.1 + 0.2).toBe(0.3) fail in Jest?
3. Which matcher correctly and safely handles the floating-point comparison above?
4. What is a risk of asserting expect(deletedRecord).toBeFalsy() to confirm deletion?
5. Which matcher would you use to assert a score is at least 60?
Was this page helpful?
You May Also Like
Common Matchers: toBe, toEqual, toContain
Learn how Jest's core matchers toBe, toEqual, and toContain compare values, objects, and collections, and when to reach for each one.
Testing Exceptions with toThrow
Learn how to assert that a function throws an error using toThrow, including matching messages, error types, and async rejections.
Testing Async Code: Promises and async/await
Learn the correct patterns for testing promise-based and async/await code in Jest, and the pitfalls that let async bugs slip past a green test run.