To effectively use Jest matchers for robust unit testing, here are the detailed steps to get you started quickly:
👉 Skip the hassle and get the ready to use 100% working script (Link in the comments section of the YouTube Video) (Latest test 31/05/2025)
Check more on: How to Bypass Cloudflare Turnstile & Cloudflare WAF – Reddit, How to Bypass Cloudflare Turnstile, Cloudflare WAF & reCAPTCHA v3 – Medium, How to Bypass Cloudflare Turnstile, WAF & reCAPTCHA v3 – LinkedIn Article
First, ensure Jest is installed in your project. If not, you can add it via npm: npm install --save-dev jest
. Next, create a test file e.g., my-module.test.js
alongside the code you want to test. Inside this file, you’ll import the function or module and then write your tests. The core of Jest’s assertion lies with expect
, which wraps the value you want to test, followed by a matcher that performs the actual comparison. For instance, expectsum1, 2.toBe3.
uses the toBe
matcher to check for exact equality. For truthiness, expecttrue.toBeTruthy.
is your go-to. If you’re dealing with objects or arrays, toEqual
is crucial as toBe
only checks for reference equality. To check if an array contains a specific item, toContain
is incredibly handy, like expect.toContain2.
. When dealing with asynchronous code, expect.resolves.toBe
or expect.rejects.toThrow
are your allies. Remember to use async/await
with these to ensure the test waits for the promise to settle. Finally, run your tests using npm test
or jest
from your terminal. This streamlined approach allows you to quickly assert various conditions and ensure your code behaves as expected, fostering a reliable development workflow.
The Foundation: Understanding Jest Matchers
Jest matchers are the backbone of effective testing, acting as the assertion methods you call on the expect
function.
Think of them as specialized comparison operators that allow you to check a wide array of conditions, from simple value equality to complex object structures, asynchronous results, and even mocking interactions. Without matchers, expect
would be a shell.
It’s the matcher that gives your test its specific purpose and verifies the behavior of your code.
Mastering them is key to writing expressive, readable, and truly impactful unit tests.
What are Jest Matchers?
Jest matchers are functions attached to the expect
object that allow you to make assertions about the value you’re testing.
When you write expectsomeValue.toBeanotherValue.
, toBe
is the matcher.
These matchers are designed to handle various types of comparisons, ensuring that your tests can accurately reflect the intended behavior of your application.
They provide a rich API to cover almost any testing scenario you might encounter.
For instance, simple equality checks are handled by toBe
, while toEqual
is crucial for deep equality comparisons of objects and arrays.
According to a 2023 survey by State of JS, Jest remains one of the most widely adopted testing frameworks, with its intuitive matcher API being a significant factor in its popularity, used by over 70% of JavaScript developers who write tests. Cypress stubbing
Why are Matchers Essential for Testing?
Matchers are essential because they provide the specific logic for assertion.
Without them, you would have to write custom comparison functions for every type of check, leading to verbose, repetitive, and error-prone tests.
Matchers abstract away this complexity, offering a concise and standardized way to express your expectations.
They improve test readability, making it easier for anyone to understand what a test is verifying.
Furthermore, Jest’s matchers provide detailed error messages when a test fails, pinpointing exactly why an assertion didn’t pass.
This rapid feedback loop is critical for debugging and maintaining high-quality code.
For example, failing expect{a: 1}.toEqual{b: 2}.
gives a clear diff, saving significant debugging time compared to a generic assertobj1 === obj2
that just returns false.
Basic Syntax: expectvalue.matcherexpected
The fundamental syntax for using Jest matchers is straightforward: expectvalue.matcherexpected
. Here, value
is the actual output or state of your code that you want to test.
matcher
is the specific assertion method you choose e.g., toBe
, toEqual
, toBeTruthy
. expected
is the value you anticipate value
to be.
This consistent structure makes it easy to write and read tests. Junit used for which type of testing
For example, expectadd2, 3.toBe5.
clearly states that you expect the result of add2, 3
to be 5
. This predictable pattern helps developers quickly grasp the intent of each test case.
Core Matchers for Equality and Truthiness
When it comes to asserting basic conditions in your Jest tests, a handful of core matchers will become your daily companions.
These matchers handle the most common scenarios: checking if two values are identical, if two objects have the same content, and if a value evaluates to true or false.
Understanding the subtle differences between toBe
and toEqual
, and knowing when to use toBeTruthy
versus toBeDefined
, is fundamental to writing accurate and effective unit tests.
toBe
: Strict Equality for Primitives
The toBe
matcher is used for strict equality checks, akin to the ===
operator in JavaScript.
It’s primarily used for primitive values like numbers, strings, booleans, null
, and undefined
. When you use toBe
, Jest checks if the two values are precisely the same in both value and type.
It also checks for reference equality for objects, meaning expect{a: 1}.toBe{a: 1}
will fail because they are two distinct objects in memory, even if their contents are identical.
expect5.toBe5.
passes, expect"hello".toBe"hello".
passes.
However, expecttrue.toBe1.
fails because true
is a boolean and 1
is a number, even though they might be considered “truthy” in some contexts.
This strictness is vital for ensuring your code produces the exact output expected. Noalertpresentexception in selenium
toEqual
: Deep Equality for Objects and Arrays
Unlike toBe
, the toEqual
matcher is designed for deep equality checks, making it ideal for comparing objects and arrays.
When you use toEqual
, Jest recursively checks every field of an object or every element of an array to ensure they are identical.
This means expect{a: 1, b: 2}.toEqual{a: 1, b: 2}.
will pass, as will expect.toEqual.
. This is incredibly powerful because it allows you to assert that two complex data structures have the same content, regardless of whether they are the exact same object in memory.
This matcher is indispensable when testing functions that return objects or arrays, where you care about the data’s content rather than its memory reference. A common mistake is using toBe
for objects.
toEqual
is almost always what you need for non-primitive comparisons.
toBeTruthy
and toBeFalsy
: Checking for Truthiness
Jest provides matchers to check for truthiness and falsiness, which align with JavaScript’s concept of how values evaluate in a boolean context.
toBeTruthy
: This matcher passes if the value is truthy i.e., evaluates totrue
in a boolean context. Examples includeexpect1.toBeTruthy.
,expect"hello".toBeTruthy.
,expect{}.toBeTruthy.
, andexpect.toBeTruthy.
.toBeFalsy
: This matcher passes if the value is falsy i.e., evaluates tofalse
in a boolean context. Examples includeexpect0.toBeFalsy.
,expect"".toBeFalsy.
,expectnull.toBeFalsy.
,expectundefined.toBeFalsy.
, andexpectNaN.toBeFalsy.
.
These matchers are particularly useful when you’re testing functions that return values whose truthiness or falsiness is significant to their behavior, such as a function that validates user input.
toBeNull
, toBeUndefined
, toBeDefined
: Specific Null/Undefined Checks
For more precise checks related to null
and undefined
, Jest offers dedicated matchers:
toBeNull
: This matcher passes only if the value isnull
.expectnull.toBeNull.
passes, butexpectundefined.toBeNull.
fails.toBeUndefined
: This matcher passes only if the value isundefined
.expectundefined.toBeUndefined.
passes, butexpectnull.toBeUndefined.
fails.toBeDefined
: This matcher passes if the value is anything other thanundefined
. This is the inverse oftoBeUndefined
.expect0.toBeDefined.
,expect"".toBeDefined.
,expectnull.toBeDefined.
all pass.
These specific matchers are more explicit and robust than toBeTruthy
or toBeFalsy
when you specifically need to assert the presence or absence of null
or undefined
, reducing ambiguity in your tests.
For instance, if a function might return null
on error, expectresult.toBeNull.
is much clearer than expectresult.toBeFalsy.
because toBeFalsy
would also pass for 0
, ''
, or undefined
. Aab file
Numeric Matchers for Quantitative Assertions
Testing numerical outputs is a frequent requirement in many applications, especially those dealing with calculations, financial data, or scientific measurements.
Jest provides a comprehensive set of matchers tailored for quantitative assertions, allowing you to check for specific values, ranges, and floating-point precision with ease.
These matchers are indispensable for ensuring the accuracy and correctness of your numerical logic.
toBeGreaterThan
, toBeGreaterThanOrEqual
These matchers allow you to assert if a numerical value is greater than or greater than or equal to a specified number.
toBeGreaterThannumber
: Checks if the actual value is strictly greater than the expected number. For example,expect10.toBeGreaterThan5.
passes, butexpect5.toBeGreaterThan5.
fails.toBeGreaterThanOrEqualnumber
: Checks if the actual value is greater than or equal to the expected number. For example,expect10.toBeGreaterThanOrEqual5.
passes, andexpect5.toBeGreaterThanOrEqual5.
also passes.
These are particularly useful when testing conditions where minimum thresholds or increasing values are critical.
For instance, ensuring a user’s age is above a certain limit, or that a calculated discount is at least a specific percentage.
In financial applications, ensuring minimum balance requirements or minimum transaction amounts are met relies heavily on these matchers.
toBeLessThan
, toBeLessThanOrEqual
Conversely, these matchers allow you to assert if a numerical value is less than or less than or equal to a specified number.
toBeLessThannumber
: Checks if the actual value is strictly less than the expected number. For example,expect5.toBeLessThan10.
passes, butexpect10.toBeLessThan10.
fails.toBeLessThanOrEqualnumber
: Checks if the actual value is less than or equal to the expected number. For example,expect5.toBeLessThanOrEqual10.
passes, andexpect10.toBeLessThanOrEqual10.
also passes.
These are valuable for verifying maximum limits, such as ensuring a quantity does not exceed inventory, or that a processing time remains below a certain threshold.
In performance testing, you might use these to assert that a function executes within an acceptable time limit. Rest api
According to industry benchmarks, optimized financial transaction processing often aims for latency below 50 milliseconds, which could be tested using expectprocessingTime.toBeLessThan50.
.
toBeCloseTo
: Handling Floating-Point Precision
Floating-point arithmetic can introduce subtle precision issues, making direct equality checks toBe
unreliable for decimal numbers.
The toBeCloseTo
matcher addresses this by allowing you to compare two floating-point numbers within a specified number of decimal places of precision.
toBeCloseToexpected, numDigits
: Checks if the actual value is close to the expected value. ThenumDigits
argument optional, defaults to 2 specifies the number of decimal places of precision to check. For example,expect0.1 + 0.2.toBeCloseTo0.3.
passes, whereasexpect0.1 + 0.2.toBe0.3.
would typically fail due to floating-point inaccuracies0.30000000000000004
.
This matcher is crucial for financial calculations, scientific simulations, or any scenario where precise decimal comparisons are necessary.
It prevents flaky tests caused by the inherent limitations of floating-point representation.
A common use case is verifying currency conversions or calculations involving percentages, where slight rounding differences can occur but should still be considered correct within a given tolerance.
String and Array Matchers for Collection and Content Verification
When your code interacts with strings and collections like arrays, Jest provides a powerful suite of matchers to assert their content and structure.
These matchers go beyond simple equality, allowing you to check for substring presence, array inclusion, and specific patterns, which are invaluable for validating data processing, search functionalities, and data transformation operations.
toMatch
: Matching Against Regular Expressions
The toMatch
matcher is incredibly useful for validating string content against a regular expression.
This is particularly handy when you need to ensure a string conforms to a specific format, contains certain patterns, or excludes undesirable characters, without having to check for exact string equality. Cypress clock
toMatchregexp | string
: Checks if the string matches the provided regular expression or contains the substring.- Example with RegExp:
expect'The quick brown fox'.toMatch/fox/.
passes.expect'[email protected]'.toMatch/^\S+@\S+\.\S+$/.
can validate an email format. - Example with substring:
expect'Hello World'.toMatch'World'.
also passes.
- Example with RegExp:
This matcher is indispensable for testing input validation e.g., ensuring a phone number is in the correct format, parsing logic e.g., extracting data from a log string, or verifying the structure of dynamic text content.
For instance, if you’re building a content management system, you might use toMatch
to ensure that generated slugs are lowercase and contain only hyphens.
toContain
: Checking for Item Presence in Arrays or Iterables
The toContain
matcher is a highly versatile tool for asserting that an item exists within an array or any iterable like a Set or Map’s values. It checks for equality of elements, not references, making it suitable for both primitive and object elements within a collection.
toContainitem
: Checks ifitem
is present in the array or iterable.- Example with primitives:
expect.toContain2.
passes. - Example with objects uses deep equality for objects if it’s within the array:
const user = { id: 1, name: 'Alice' }. expect.toContainuser.
will pass ifuser
object is a reference to one of the objects in the array. However, ifuser
is a new object with identical properties,toContain
will typically fail for objects unless you use custom matchers orarrayContaining
. For simple objects,expectsomeArray.toEqualexpect.arrayContaining
is often preferred.
- Example with primitives:
This matcher is vital for testing search results, filtering logic, or ensuring that a collection includes a newly added item.
For example, if you add an item to a shopping cart, expectcart.items.toContainnewItem.
can verify its addition.
toHaveLength
: Asserting Collection Size
The toHaveLength
matcher is a simple yet powerful way to assert the number of elements in an array or the number of characters in a string.
It directly checks the length
property of the tested value.
toHaveLengthnumber
: Checks if the value has alength
property equal tonumber
.- Example with array:
expect.toHaveLength3.
passes. - Example with string:
expect'hello'.toHaveLength5.
passes.
- Example with array:
This matcher is crucial for verifying that data processing functions produce collections of the expected size, such as ensuring a pagination function returns exactly 10 results per page, or that a validation function filters out the correct number of invalid entries.
For instance, in a data cleaning pipeline, expectcleanedData.toHaveLengthinitialData.length - removedInvalidEntries.
can ensure the correct number of entries remain.
Exception and Asynchronous Matchers for Robustness
Modern JavaScript applications heavily rely on error handling and asynchronous operations. Cypress window method
Jest provides specialized matchers to effectively test these critical aspects of your code.
Being able to assert that a function throws a specific error, or that an asynchronous operation resolves or rejects as expected, is fundamental to building reliable and robust applications.
toThrow
: Testing for Thrown Errors
The toThrow
matcher is used to assert that a function throws an error when executed.
This is essential for validating error handling logic and ensuring your application gracefully manages invalid inputs or unexpected conditions.
toThrowerror | string | RegExp | errorClass
: Checks if the function throws an error.- No arguments: Checks if any error is thrown.
expect => throwError.toThrow.
- String: Checks if the error message contains the specified string.
expect => throwError"Invalid input".toThrow"Invalid input".
- RegExp: Checks if the error message matches the regular expression.
expect => throwError"User ID 123 not found".toThrow/ID \d+/.
- Error Class: Checks if the thrown error is an instance of a specific error class.
expect => throwCustomError.toThrowCustomError.
- No arguments: Checks if any error is thrown.
When using toThrow
, you must wrap the function call in an arrow function e.g., => myFunction
. If you call myFunction
directly, Jest will execute it immediately, and if it throws, the test will fail before toThrow
can even be called.
This matcher is vital for unit testing validation functions, API error responses, and any code paths designed to signal failure through exceptions.
For example, ensuring a withdraw
function throws an error if the balance is insufficient.
resolves
and rejects
: Handling Promises
Asynchronous code, particularly Promises, is ubiquitous in modern web development.
Jest offers powerful resolves
and rejects
matchers to test the outcome of promises.
These allow you to chain matchers directly onto the promise, ensuring that the promise resolves with an expected value or rejects with a specific error. Software testing standards
expectpromise.resolves.matcherexpected
: Checks if a promise resolves successfully with a value that satisfies the subsequent matcher. You mustawait
theexpect
call when usingresolves
.- Example:
await expectfetchData.resolves.toBe'data'.
orawait expectgetUser123.resolves.toEqual{ id: 123, name: 'Alice' }.
- Example:
expectpromise.rejects.matcherexpected
: Checks if a promise rejects with an error that satisfies the subsequent matcher. You must alsoawait
theexpect
call when usingrejects
.- Example:
await expectfailedOperation.rejects.toThrow'Network error'.
orawait expectvalidateCredentials.rejects.toBeInstanceOfAuthError.
- Example:
These matchers are indispensable for testing API calls, database interactions, file I/O operations, or any function that returns a Promise.
They provide a clear and concise way to ensure your asynchronous logic behaves correctly under both success and failure conditions.
According to a 2022 survey, over 85% of JavaScript applications leverage asynchronous programming, underscoring the importance of these matchers for comprehensive test coverage.
Mocking Matchers for Controlled Environments
In unit testing, isolating the “unit” under test is crucial.
This often means controlling its dependencies, such as external functions, modules, or network requests.
Jest’s mocking capabilities, combined with specific matchers, allow you to replace real dependencies with “mock” versions, giving you complete control over their behavior and providing insights into how they were called.
toHaveBeenCalled
and toHaveBeenCalledWith
When you mock functions, you often need to verify that they were called and with what arguments.
Jest’s mock
functions come with built-in matchers for this purpose.
toHaveBeenCalled
: Asserts that a mock function was called at least once.- Example:
const mockFn = jest.fn. mockFn. expectmockFn.toHaveBeenCalled.
- Example:
toHaveBeenCalledWith...args
: Asserts that a mock function was called with specific arguments at least once. The arguments must match exactly.- Example:
const mockFn = jest.fn. mockFn1, 'a'. expectmockFn.toHaveBeenCalledWith1, 'a'.
- Example:
These matchers are fundamental for testing side effects, callbacks, or integrations with other modules.
For instance, if you’re testing a user registration function, you might mock the email sending service and then use toHaveBeenCalledWith
to ensure the email function was called with the correct recipient and message. Salesforce test automation tools
This ensures your application’s logic is correctly orchestrating interactions with its dependencies.
toHaveBeenLastCalledWith
and toHaveBeenCalledTimes
For more granular control over mock function calls, Jest provides matchers that check the last call and the total number of calls.
toHaveBeenLastCalledWith...args
: Asserts that a mock function was called with specific arguments in its last invocation. This is useful when a function might be called multiple times but you’re only concerned with the final interaction.- Example:
const mockFn = jest.fn. mockFn1. mockFn2. expectmockFn.toHaveBeenLastCalledWith2.
- Example:
toHaveBeenCalledTimesnumber
: Asserts that a mock function was called a specific number of times. This is perfect for ensuring loops, retries, or batch processing functions are executed the expected number of times.- Example:
const mockFn = jest.fn. for let i = 0. i < 3. i++ mockFn. expectmockFn.toHaveBeenCalledTimes3.
- Example:
These matchers provide precise insights into the execution flow of your code, ensuring that mocked dependencies are interacted with exactly as intended, preventing subtle bugs in complex workflows.
In a real-world scenario, you might test a retry mechanism, verifying that an API call was attempted three times before giving up.
toHaveReturned
and toHaveReturnedWith
Beyond verifying calls, you might also want to assert what values mock functions returned.
toHaveReturned
: Asserts that a mock function has returned at least once.- Example:
const mockFn = jest.fn => true. mockFn. expectmockFn.toHaveReturned.
- Example:
toHaveReturnedWithvalue
: Asserts that a mock function has returned with a specific value at least once.- Example:
const mockFn = jest.fn => 5. mockFn. expectmockFn.toHaveReturnedWith5.
- Example:
These matchers are useful when you want to verify the output of a mocked dependency, especially in cases where the consuming function relies on that output.
For example, if you mock a data fetching function, you might assert that it returned specific data that then feeds into another part of your system.
This helps ensure that the mocked dependency provides the expected data shape or values.
Extending Jest: Custom Matchers
While Jest’s built-in matchers cover a vast array of testing scenarios, there are times when your application’s specific logic or domain-specific data structures require unique assertions. This is where custom matchers shine.
They allow you to define your own assertion logic, making your tests more expressive, readable, and maintainable, especially for complex or frequently repeated checks. Run javascript code in browser
When to Create Custom Matchers
You should consider creating custom matchers when:
- You have repetitive assertion logic: If you find yourself writing the same
expect.toBe
orexpect.toEqual
checks multiple times across different tests for a specific type of object or condition, a custom matcher can abstract this redundancy. - You want to improve readability: A well-named custom matcher can significantly enhance the clarity of your tests, making them more declarative and easier to understand at a glance. Instead of
expectuser.email.toMatch/@example.com$/ && expectuser.id.toBeDefined.
, you could haveexpectuser.toBeValidUser.
. - You need domain-specific assertions: Your application might have unique concepts or data structures e.g., a custom
Money
object, aUser
entity with specific validation rules that require specialized comparison logic. Custom matchers allow you to encapsulate this logic. - You need better error messages: Jest’s default error messages are good, but custom matchers allow you to craft highly descriptive and actionable failure messages tailored to your specific assertion, which greatly aids debugging.
A study by Google found that well-designed test suites with high readability can reduce debugging time by up to 15%, highlighting the value of expressive tests.
How to Implement a Custom Matcher
Implementing a custom matcher involves adding a function to Jest’s expect.extend
method.
Each matcher function receives the received
value the argument passed to expect
and any expected
arguments passed to the matcher itself.
It must return an object with a pass
boolean indicating if the assertion passed and a message
function which returns the error message for failures.
expect.extend{
// Matcher for checking if a string is a valid email simple example
toBeValidEmailreceived {
const pass = /^+@+\.+$/.testreceived.
if pass {
return {
message: => `expected ${received} not to be a valid email`,
pass: true,
}.
} else {
message: => `expected ${received} to be a valid email`,
pass: false,
}
},
// Matcher for checking if an object has specific properties
toHaveAllPropertiesreceived, properties {
const missing = properties.filterprop => !prop in received.
const pass = missing.length === 0.
message: => `expected object not to have all properties: ${properties.join', '}`,
message: => `expected object to have all properties: ${properties.join', '}. Missing: ${missing.join', '}`,
}.
You would typically put this expect.extend
call in a setup file that Jest runs before your tests e.g., in jest.setup.js
and configured in jest.config.js
under setupFilesAfterEnv
.
Using Custom Matchers in Your Tests
Once defined, your custom matchers can be used just like any other built-in Jest matcher:
// Assuming the custom matchers above are loaded via setupFilesAfterEnv
describe’User Validation’, => {
test’should validate a correct email address’, => {
expect’[email protected]‘.toBeValidEmail.
}. Mainframe testing
test’should not validate an invalid email address’, => {
expect'invalid-email'.not.toBeValidEmail. // Using .not with custom matchers
test’should ensure user object has required properties’, => {
const user = { id: 1, name: 'John Doe', email: '[email protected]' }.
expectuser.toHaveAllProperties.
test’should fail if user object is missing properties’, => {
const user = { id: 1, name: ‘John Doe’ }.
expectuser.not.toHaveAllProperties.
Custom matchers make your test suite more idiomatic and tailored to your codebase, leading to cleaner, more efficient, and more maintainable tests.
They are a powerful feature for teams looking to establish consistent testing patterns and improve developer experience.
Best Practices and Common Pitfalls
Writing effective unit tests with Jest matchers goes beyond simply knowing which matcher to use.
It involves adopting best practices that lead to maintainable, readable, and robust test suites, while also being aware of common pitfalls that can undermine your testing efforts.
Adhering to these guidelines will significantly improve the quality and longevity of your tests.
Keeping Tests Focused and Atomic
One of the most crucial best practices is to keep your tests focused and atomic. This means:
- Single Responsibility Principle SRP for Tests: Each test case
it
ortest
block should ideally test one specific piece of functionality or one specific outcome. This makes tests easier to understand, debug, and maintain. If a test fails, you know exactly what behavior broke. - Independent Tests: Tests should not depend on the order of execution or on the state left by previous tests. Use
beforeEach
andafterEach
hooks to set up and tear down a clean environment for each test. This ensures reproducibility and prevents “flaky” tests that pass or fail inconsistently. - Minimize Assertions per Test: While not a strict rule, generally, a test should have one logical assertion. If you need multiple assertions for different aspects of a single outcome, ensure they are tightly related. Too many unrelated assertions in one test can make it hard to pinpoint the failure. For example, testing
expectuser.name.toBe'Alice'.
andexpectuser.age.toBe30.
in the same test is acceptable if you’re testing the complete user object creation, but mixing it withexpectdatabase.save.toHaveBeenCalled.
might warrant a separate test.
Using .not
for Negative Assertions
Jest matchers can be negated using the .not
property, which makes your negative assertions explicit and readable. Hotfix vs coldfix
- Clarity: Instead of trying to find a “negative” matcher which often doesn’t exist, you simply prepend
.not
to the positive matcher. For example,expectvalue.not.toBeNull.
is much clearer than trying to find anotToBeNull
matcher. - Examples:
expectresult.not.toBeUndefined.
ensuresresult
is definedexpectmyArray.not.toContain'item'.
ensuresitem
is not inmyArray
expect => someFunc.not.toThrow.
ensuressomeFunc
does not throw an error
Using.not
properly improves the expressiveness of your tests, allowing you to clearly state what should not happen.
Common Pitfalls to Avoid
- Using
toBe
for Objects/Arrays: This is perhaps the most common pitfall.toBe
checks for reference equality. For content equality of objects and arrays, always usetoEqual
.- Bad:
expect{a: 1}.toBe{a: 1}.
Fails - Good:
expect{a: 1}.toEqual{a: 1}.
Passes
- Bad:
- Not
await
ing Async Matchers: When usingresolves
orrejects
, you mustawait
theexpect
call. Forgettingawait
will cause your test to complete before the promise settles, leading to false positives or unexpected behavior.- Bad:
expectasyncFn.resolves.toBetrue.
Might pass but is buggy - Good:
await expectasyncFn.resolves.toBetrue.
- Bad:
- Not Wrapping
toThrow
in a Function: As mentioned earlier,toThrow
must receive a function that, when executed, might throw an error. If you call the function directly, Jest won’t be able to catch the error for assertion.- Bad:
expectmyFunctionWhichThrows.toThrow'error'.
- Good:
expect => myFunctionWhichThrows.toThrow'error'.
- Bad:
- Over-mocking: Mocking too many dependencies can make tests brittle and hard to understand. Only mock what’s necessary to isolate the unit under test. Excessive mocking can also hide real integration issues.
- Flaky Tests: Tests that sometimes pass and sometimes fail without code changes are “flaky.” Common causes include reliance on external factors time, network, improper asynchronous handling, or shared state between tests. Debugging flaky tests is crucial for a reliable test suite.
By adopting these best practices and being vigilant against common pitfalls, you can build a Jest test suite that is effective, maintainable, and provides true confidence in your application’s reliability.
Frequently Asked Questions
What are Jest matchers?
Jest matchers are special functions, like toBe
or toEqual
, that you chain onto expect
to assert conditions about the value you’re testing.
They provide specific comparison logic and clear error messages, forming the core of Jest’s assertion API.
How do I use toBe
in Jest?
You use toBe
for strict equality comparisons like ===
primarily for primitive values such as numbers, strings, and booleans.
For example: expect5.toBe5.
or expect"hello".toBe"hello".
.
When should I use toEqual
instead of toBe
?
You should use toEqual
when comparing objects or arrays, as it performs a deep equality check, recursively comparing their contents.
toBe
only checks for reference equality for non-primitive types, meaning expect{a: 1}.toBe{a: 1}.
would fail.
How do I test for truthiness or falsiness in Jest?
You use toBeTruthy
to check if a value evaluates to true
in a boolean context e.g., expect1.toBeTruthy.
and toBeFalsy
to check if a value evaluates to false
e.g., expect0.toBeFalsy.
.
What’s the difference between toBeNull
and toBeUndefined
?
toBeNull
asserts that a value is strictly null
expectnull.toBeNull.
. toBeUndefined
asserts that a value is strictly undefined
expectundefined.toBeUndefined.
. They are more specific than toBeFalsy
.
How can I test if a number is greater than another in Jest?
You can use toBeGreaterThannumber
e.g., expect10.toBeGreaterThan5.
or toBeGreaterThanOrEqualnumber
e.g., expect10.toBeGreaterThanOrEqual10.
. User acceptance testing tools
How do I handle floating-point precision issues in tests?
Use toBeCloseToexpected, numDigits
for floating-point comparisons.
This matcher allows for slight differences within a specified precision, preventing tests from failing due to typical JavaScript floating-point inaccuracies. Example: expect0.1 + 0.2.toBeCloseTo0.3.
.
How can I test if a string matches a regular expression?
Use the toMatchregexp
matcher.
For instance, expect'[email protected]'.toMatch/@/.
will pass if the string contains the @
symbol.
You can also pass a string to check for substrings, like expect'Hello World'.toMatch'World'.
.
What is toContain
used for?
toContainitem
is used to check if an array or any iterable contains a specific item.
For example, expect.toContain2.
or expect.toContain'apple'.
.
How do I check the length of an array or string?
You use toHaveLengthnumber
. This matcher checks the length
property of the received value.
Example: expect.toHaveLength3.
or expect"test".toHaveLength4.
.
How do I test if a function throws an error?
Wrap the function call in an arrow function and use toThrow
. For example, expect => myFunctionThatThrows.toThrow'Expected error message'.
. Reusability of code
How do I test asynchronous code Promises in Jest?
For Promises that resolve, use await expectpromise.resolves.matcherexpected.
. For Promises that reject, use await expectpromise.rejects.matcherexpected.
. Remember to use async/await
in your test function.
How do I check if a mock function was called?
Use toHaveBeenCalled
to check if a mock function was called at least once.
Example: const mockFn = jest.fn. mockFn. expectmockFn.toHaveBeenCalled.
.
How do I check if a mock function was called with specific arguments?
Use toHaveBeenCalledWith...args
. For instance, const mockFn = jest.fn. mockFn'data', 123. expectmockFn.toHaveBeenCalledWith'data', 123.
.
Can I check how many times a mock function was called?
Yes, use toHaveBeenCalledTimesnumber
. Example: const mockFn = jest.fn. mockFn. mockFn. expectmockFn.toHaveBeenCalledTimes2.
.
What is a custom matcher in Jest?
A custom matcher is a user-defined assertion function that extends Jest’s expect
API.
It allows you to create specialized, readable assertions for your application’s unique logic or data structures.
When should I create a custom matcher?
Create a custom matcher when you have repetitive assertion logic, need to improve test readability for domain-specific checks, or want to provide more specific error messages for complex scenarios.
How do I implement a custom matcher?
You implement a custom matcher by using expect.extend{}
and defining a function that returns an object with a pass
boolean and a message
function.
This function receives the received
value and any expected
arguments. What is field testing
Can I use .not
with custom matchers?
Yes, custom matchers fully support the .not
modifier, allowing you to express negative assertions clearly.
If your custom matcher is toBeValid
, you can use expectvalue.not.toBeValid.
.
What are some common pitfalls when using Jest matchers?
Common pitfalls include using toBe
for objects/arrays instead of toEqual
, forgetting to await
asynchronous matchers resolves
/rejects
, and not wrapping the function call when using toThrow
.
Leave a Reply