React Testing for Beginners
Jest Explained
src/App.test.js


Writing Unit Tests with Jest
Unit Test - should test just one thing
src/App.js
src/App.test.js

Writing Integration Tests
Tests where one unit interacts with another unit
src/App.js
src/App.test.js
Mock Functions & Why
mock a function that may not be accessible to the current test. However, an assertion relies on what comes back from that function in order to test what it needs to test in the function it is designed to test
mock api calls
mock database calls
src/App.test.js

Mocking Modules
mock the import and then mock the implementation of what we mock imported
src/add.js
src/add.test.js
src/App/js
src/App.test.js

React Testing Library & Debug
src/example_components/Counter.js
src/example_components/Counter.test.js
Output from line 7 of Counter.test.js

easy way to get some visibilty on our
<Counter />
componentif you added
console.log(wrapper.getByText('0'));
inside the callback of the test function, the following output in the console would be the actual DOM node.

from here you can then add on something like
console.log(wrapper.getByText('0').tagName);
and get:

src/example_components/Counter.test.js

Testing with Test Ids
One of the big differences between using React-Testing-Library and a third-party library such as Enzyme (Enzyme is no longer going to be kept up after React 17) is in Enzyme you could look up a component by the component name. Sounds great and easy, however, users don't know the component name or interact with the component directly. In React-Testing-Library
you look up an element just as it is in the DOM. This is how a user interacts with your app, through the DOM. And you should test your app the way a user will interact with it.
src/example_components/Counter.js
refactor
Counter.test.js
file to below.destructure out
debug
andgetByTestId
from the<Counter />
componentconst { debug, getByTestId } = render(<Counter />);
now have access to
debug
andgetByTestId
directly
src/example_components/Counter.test.js

Events in React Testing Library
can simulate events by using
fireEvent
do NOT have to have the app running to use these tests
you do not need to check state with React-Testing-Library
src/example_components/Counter.js
refactor
Counter.test.js
again by usingconst counterBtn = getByTestId('counter-button');
replace
getByTestId('counter-button')
withcounterBtn
src/example_components/Counter.test.js
test output before adding the counter functionality to
Counter.js

test output after adding the counter functionality to
Counter.js
Integration Testing in React & Cleanup
src/NewMovie.js
src/MovieForm.js
src/NewMovie.test.js
initial output with just skeleton files and test

getByTestId
will return an error if it cannot find the element—it MUST be there or throw an errorqueryByTestId
is slightly different, it just sees if there or nothing
Snapshot Testing 101
generally better off with manual tests
however, snapshot testing is really good for a component that does not change very often if hardly ever
then you can check the component to see if something changed
fragile tests
they are easy and fast and very good in the right context
expect(container.firstChild).toMatchSnapshot();
src/NewMovie.test.js
once this run when the test runs, creates a folder called
__snapshots__
undersrc
and puts all snapshots thereeach and every time thereafter, it runs a new snapshot (does not save it under the folder) and compares it to the one stored
failed snapshot test

if this was a legitimate change, then you can press 'u' while the terminal has focus, and it will update the snapshot, else fix the issue and rerun
DO NOT rely on snapshot tests for your only testing
Spying & Mocking Functions in React
src/MovieForm.js
src/MovieForm.test.js
Form Events With Controlled Inputs
src/MovieForm.js
src/MovieForm.test.js
Testing for Errors & Global Mocks
src/Movie.js
src/Movie.test.js
Negative Assertions & Testing With React Router
src/Movie.test.js

src/Movie.test.js

pitfall:
console.error
spy has been called in a previous test when the movie was undefined.mock functions remember when they have been called during the current testing session
therefore, the spy function needs to be reset
src/Movie.test.js

What To Test
don't want to test to make sure React is doing its job
you want to test to make sure the app is doing what the user is expecting it to do
expect(getByTestId('movie-link').href);
can do it this way, however, remember locally running on localhost and this would return the absolute path to include https and make out test brittle
expect(getByTestId('movie-link').getAttribute('href'));
better way because this would return the relative path instead
src/Movie.test.js

src/Movie.test.js

tested to make sure the link href was correctly set
src/Movie.test.js

tests to make sure the image src is set correctly
Mocking Fetch
need to add
jest-fetch-mock
-npm install jest-fetch-mock
src/MovieDetail.test.js

notice though we have no h1, h3, p
even though we mocked the fetch and response, since this is an async call, it still takes time and then re-renders when the data comes back
debug()
on the other hand outputs before that data has come back
Mocking Fetch Part 2 & Async Tests & Working With Data
src/MovieDetail.test.js

Testing Loading States & More Pitfalls
src/MoviesList.js
src/MoviesList.test.js

Refactoring with Tests
src/movies/MoviesList.js
src/movies/tests /MoviesList.test.js

Code Coverage
yarn test --coverage
