Take a really simple button component as below.
const Button = () => (
<button
onClick={() => {
window.localStorage.setItem('clicked', 'yes')
}}
>
Click Me
</button>
)
We want to write a test that asserts the interaction with localStorage
when the button is clicked. To do this is pretty simple.
import * as React from 'react'
import Button from './Button'
import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
describe('Button', () => {
jest.spyOn(Object.getPrototypeOf(window.localStorage), 'setItem')
Object.setPrototypeOf(window.localStorage.setItem, jest.fn())
})
As you can see, the first thing we do is add a Jest spy function which will watch the setItem
method of localStorage
.
In addition, it then mocks this to a jest.fn()
so we can use it in an assertion later.
import * as React from 'react'
import Button from './Button'
import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
describe('Button', () => {
jest.spyOn(Object.getPrototypeOf(window.localStorage), 'setItem')
Object.setPrototypeOf(window.localStorage.setItem, jest.fn())
it('calls localStorage.setItem when clicked', () => {
render(<Button />)
userEvent.click(screen.getByRole('button', { name: 'Click Me' }))
expect(window.localStorage.setItem).toHaveBeenCalledWith('clicked', 'yes')
})
})
As we are using @testing-library/react, we first render the component, then click the Button using userEvent
which then allows us to assert the localStorage call.