I recently started hosting AMA-style cafe chats with developers at various stages of their journey, about software engineering and anything else within my technical experience. Below are some rough & rapid-fire notes from the chat on Oct 21st, 2022.
You can test at various levels, from an individual function that knows nothing about browsers to an entire application running in a real browser and hitting real network services.
Testing small or medium-sized interactions in a simulated browser environment is a good middle ground — approachable yet useful.
Pick a basic interaction and write it down:
“when button ‘About’ is clicked, modal with information appears”.
Stick to interactions where the UI is both the input and the output channel.
Install & set up jest
, jest-environment-jsdom
, @testing-library/react
, and @testing-library/jest-dom
.
Pick a component high enough in your app’s tree to support the chosen interaction. Don’t be afraid to use <App/>
itself.
Write a <component-you-picked>.test.tsx
file containing a test("when button 'About' is clicked'...)
where you render()
the component, user.click()
the button, and expect()
that the intended change happened in the UI.
The UI change might happen on the next iteration of the JavaScript event loop; use await waitFor(() => { expect(...) })
to account for it.
Use screen.debug()
to inspect the state of the DOM at any point of the test.
Continue with interactions that involve the network and repeat.
Arrange something that handles the network request within the test environment.
nock()
a request and its response, render()
the component, user.click()
the button that triggers the network request, expect()
the UI changes and/or that the request was made.
fetch
instead of one imported from isomorphic-fetch or cross-fetch): Node 18 introduces a global fetch
, so your tests might end up invoking that, and nock can’t mock it yet. Fix by adding import "cross-fetch/polyfill"
in a jest setupFile
or by importing fetch
from cross-fetch
in application code rather then relying on the global. Alternatively, you can use the mocking facilities of Node 18’s new HTTP client undici, but those are unlikely to match nock
’s for a while.As you become more comfortable with the testing machinery, explore other ways of simulating parts of your system inside the test environment:
beforeAll()
, point your components to it by passing them an apiBaseUrl
prop or context value, and let them interact with the real (albeit sandboxed) thing.jest.mock()
and spyOn()
things that your components affect in ways other than the network, e.g. third-party SDKs