"How to test the reloading of a page in next js with vitest in a simple and effective way (window.location.reload)"
27-05-2025
Test window.location.reload
in Next.js with Vitest Simply and Effectively
When building applications with Next.js, we sometimes need to test the behavior of window.location
, such as when we want to reload the page. But how do you test something so closely tied to the browser? In this quick guide, I will show you how it’s possible using Vitest.
Example: Testing Page Reload with a Button
Let’s say we want to confirm that the page reloads when a button is clicked. The component we want to test would look like this:
Component: ReloadButton.tsx
import React from 'react'; const ReloadButton = () => { const handleReload = () => { window.location.reload(); }; return ( <button onClick={handleReload} data-testid="reload-button"> Reload Page </button> ); }; export default ReloadButton;
To verify this behavior, we could write the following test:
Test: ReloadButton.test.jsx
import { render, screen, fireEvent } from '@testing-library/react'; import { describe, it, expect, vi } from 'vitest'; import ReloadButton from './ReloadButton'; describe('ReloadButton component', () => { it('should call window.location.reload when button is clicked', () => { // Store the original window.location object const originalLocation = window.location; // Mock window.location with a reload function Object.defineProperty(window, 'location', { value: { reload: vi.fn() }, writable: true, }); // Render the ReloadButton component render(<ReloadButton />); // Simulate clicking the reload button const button = screen.getByTestId('reload-button'); fireEvent.click(button); // Check that window.location.reload was called expect(window.location.reload).toHaveBeenCalled(); // Restore the original window.location object Object.defineProperty(window, 'location', { value: originalLocation, writable: true, }); }); });
Step-by-Step: What’s Happening?
- Store the original window.location object
Before making any changes, we store the original
window.location
object so we can restore it later. This prevents side effects from affecting other tests. - Mock window.location with a function
We use
Object.defineProperty
to replacewindow.location
with a mock object. This mock includes areload
function using Vitest’s mock function (vi.fn()
). - Render the ReloadButton component
We render the
ReloadButton
component using@testing-library/react
. - Simulate clicking the reload button
We simulate a user click on the reload button using
fireEvent.click
. - Check that window.location.reload was called
We confirm that the mocked
reload
function was called usingexpect
. - Restore the original window.location object
Finally, we restore the original
window.location
object to keep the global state clean.
Why is Testing window.location Important?
Mocking window.location
ensures that you can test the reload behavior without relying on the browser environment. By restoring the original state at the end of the test, you prevent errors or inconsistencies in other parts of your application or test suite.
With this method, you can confidently test even browser-dependent functionality in any Next.js project.
Glossary
Object.defineProperty
Object.defineProperty
is a JavaScript method that allows you to define or modify properties of an object with detailed control over their behavior. In this case, we use it to replace window.location
with a mock that includes a reload
function.
Main Parameters:
- Object: The object you want to add or modify a property on (in this case,
window.location
). - Property Name: The property you want to define or modify.
- Descriptor: An object that defines the behavior of the property, such as its value (
value
), whether it is writable (writable
), and more.
fireEvent.click
fireEvent.click
is a utility from the @testing-library/react
library that simulates a click event on a DOM element during a test. This is useful for replicating user behavior in an automated test.
How to use it:
- First, select the element you want to simulate (e.g., a button).
- Then, use
fireEvent.click
to trigger the event as if the user clicked it.