Search icon
Arrow left icon
All Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletters
Free Learning
Arrow right icon
Mastering React Test-Driven Development - Second Edition

You're reading from  Mastering React Test-Driven Development - Second Edition

Product type Book
Published in Sep 2022
Publisher Packt
ISBN-13 9781803247120
Pages 564 pages
Edition 2nd Edition
Languages
Author (1):
Daniel Irvine Daniel Irvine
Profile icon Daniel Irvine

Table of Contents (26) Chapters

Preface 1. Part 1 – Exploring the TDD Workflow
2. Chapter 1: First Steps with Test-Driven Development 3. Chapter 2: Rendering Lists and Detail Views 4. Chapter 3: Refactoring the Test Suite 5. Chapter 4: Test-Driving Data Input 6. Chapter 5: Adding Complex Form Interactions 7. Chapter 6: Exploring Test Doubles 8. Chapter 7: Testing useEffect and Mocking Components 9. Chapter 8: Building an Application Component 10. Part 2 – Building Application Features
11. Chapter 9: Form Validation 12. Chapter 10: Filtering and Searching Data 13. Chapter 11: Test-Driving React Router 14. Chapter 12: Test-Driving Redux 15. Chapter 13: Test-Driving GraphQL 16. Part 3 – Interactivity
17. Chapter 14: Building a Logo Interpreter 18. Chapter 15: Adding Animation 19. Chapter 16: Working with WebSockets 20. Part 4 – Behavior-Driven Development with Cucumber
21. Chapter 17: Writing Your First Cucumber Test 22. Chapter 18: Adding Features Guided by Cucumber Tests 23. Chapter 19: Understanding TDD in the Wider Testing Landscape 24. Index 25. Other Books You May Enjoy

Test-Driving React Router

React Router is a popular library of components that integrate with the browser’s own navigation system. It manipulates the browser’s address bar so that changes in your UI appear as page transitions. To the user, it seems like they are navigating between separate pages. In reality, they remain on the same page and avoid an expensive page reload.

In this chapter, we’ll refactor our example appointments system to make use of React Router. Unlike the rest of the book, this chapter is not a walkthrough. That’s because the refactoring process is quite long and laborious. Instead, we’ll look at each of the main changes in turn.

This chapter covers the following:

  • Designing React Router applications from a test-first perspective
  • Testing components within a router
  • Testing router links
  • Testing programmatic navigation

By the end of the chapter, you’ll have learned all the necessary techniques...

Technical requirements

Designing React Router applications from a test-first perspective

This section is a run-down of all the major pieces of the React Router ecosystem, just in case you’re not familiar with it. It also contains guidance on how to test a system that relies on React Router.

A list of all the React Router pieces

Here’s what you’ll be working with from the React Router library:

  • A Router component. You’ll generally have one of these, and there are a bunch of different types. The basic one is BrowserRouter but you’ll undoubtedly upgrade to HistoryRouter if you need to manipulate history outside of the router, which, since you’re writing tests, you will. In Chapter 12, Test-Driving Redux, you’ll also see how this is necessary if you’re causing page transitions to occur within Redux actions.
  • A Routes component. This is analogous to the switch statement in our existing App component. It has a list of Route children and will...

Testing components within a router

In this section, we’ll look at how to use the primary Router, Routes, and Route components.

No walkthrough in this chapter

As mentioned in the chapter introduction, this chapter does not follow the usual walkthrough approach. The examples shown here are taken from the completed refactoring of our Appointments code base, which you’ll find in the Chapter11/Complete directory of the GitHub repository.

The Router component and its test equivalent

This is a top-level component that hooks into your browser’s location mechanics. We do not generally test drive this because JSDOM doesn’t deal with page transitions, or have full support for the window.location API.

Instead, we put it in the src/index.js file:

import React from "react";
import ReactDOM from "react-dom/client";
import { BrowserRouter } from "react-router-dom";
import { App } from "./App";
ReactDOM.createRoot...

Testing router links

In this section, you’ll learn how to use and test the Link component. This component is React Router’s version of the humble HTML anchor (or a) tag.

There are two forms of the Link component that we use. The first uses the to prop as a string, for example, /addCustomer:

<Link to="/addCustomer" role="button">
  Add customer and appointment
</Link>

The second sets the to prop to an object with a search property:

<Link
    to={{
      search: objectToQueryString(queryParams),
    }}
>
  {children}
</Link>

This object form also takes a pathname property, but we can avoid setting that since the path remains the same for our use case.

We’ll look at two different ways of testing links: the standard way (by checking for hyperlinks), and the slightly more painful way of using mocks.

Checking the page...

Testing programmatic navigation

Sometimes, you’ll want to trigger a location change programmatically—in other words, without waiting for a user to click a link.

There are two ways to do this: one using the useNavigate hook, and the second using a history instance that you pass into your top-level router.

Navigation inside and outside of components

In this chapter, we’ll look at just the first method, using the hook. Later, in Chapter 12, Test-Driving Redux, we’ll use the second method to change the location within a Redux action.

The useNavigate hook is the appropriate method when you’re able to navigate from within a React component.

In the Appointments application, this happens in two places. The first is after a customer has been added and we want to move the user on to the /addAppointment route. The second is after that form has been completed and the appointment has been created—then we want to move them back to the default...

Summary

This chapter has shown you how to use React Router in a testable fashion. You have learned how to test-drive the Router, Routes, Route, and Link components. You have seen how to use the React Router useSearchParams and useNavigate hooks.

Most importantly, you’ve seen that because routes give an extra level of entry into your application, you must split your existing navigation tests into two parts: one to test that a link exists (or is followed), and one to check that if you visit that URL, the right component is displayed.

Now that we’ve successfully integrated one library, the next one shouldn’t be too tricky, right? In the next chapter, we’ll apply all the skills we’ve learned in this chapter to the integration of another library: Redux.

Exercise

In this chapter, there was no walkthrough because the refactoring process is quite involved and would have taken up a decent chunk of time and space.

Use this opportunity to try refactoring yourself. Use a systematic refactoring approach to break down the change to React Router into many small steps. At each step, you should still have working software.

You can find a guide on how to approach this type of refactoring at https://reacttdd.com/refactoring-to-react-router.

Further reading

The official React Router documentation can be found at the following link:

https://reacttraining.com/react-router/

lock icon The rest of the chapter is locked
You have been reading a chapter from
Mastering React Test-Driven Development - Second Edition
Published in: Sep 2022 Publisher: Packt ISBN-13: 9781803247120
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €14.99/month. Cancel anytime}