Reader small image

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

Product typeBook
Published inSep 2022
Reading LevelIntermediate
PublisherPackt
ISBN-139781803247120
Edition2nd Edition
Languages
Tools
Right arrow
Author (1)
Daniel Irvine
Daniel Irvine
author image
Daniel Irvine

Daniel Irvine is a UK-based software consultant. He helps businesses simplify their existing codebases and assists dev teams in improving the quality of their software using eXtreme programming (XP) practices. He has been coaching developers for many years and co-founded the Queer Code London meetup.
Read more about Daniel Irvine

Right arrow

Building an Application Component

The components you’ve built so far have been built in isolation: they don’t fit together, and there’s no workflow for the user to follow when they load the application. Up to this point, we’ve been manually testing our components by swapping them in and out of our index file, src/index.js.

In this chapter, we’ll tie all those components into a functioning system by creating a root application component, App, that displays each of these components in turn.

You have now seen almost all the TDD techniques you’ll need for test-driving React applications. This chapter covers one final technique: testing callback props.

In this chapter, we will cover the following topics:

  • Formulating a plan
  • Using state to control the active view
  • Test-driving callback props
  • Making use of callback values

By the end of this chapter, you’ll have learned how to use mocks to test the root component...

Technical requirements

Formulating a plan

Before we jump into the code for the App component, let’s do a little up-front design so that we know what we’re building.

The following diagram shows all the components you’ve built and how App will connect them:

Figure 8.1 – The component hierarchy

Here’s how it’ll work:

  1. When the user first loads the app, they will see a list of today’s appointments using the AppointmentsDayView component, which will have its appointment data populated by its container AppointmentsDayViewLoader component.
  2. At the top of the screen, the user will see a button labeled Add customer and appointment. Clicking that button makes AppointmentsDayView disappear and CustomerForm appear.
  3. When the form is filled out and the submit button is clicked, the user is shown AppointmentForm and can add a new appointment for that customer.
  4. Once they’ve added the appointment, they’ll be taken...

Using state to control the active view

In this section, we’ll start building a new App component, in the usual way. First, we’ll display an AppointmentsDayViewLoader component. Because this child component makes a network request when mounted, we’ll mock it out. Then, we’ll add a button inside a menu element, at the top of the page. When this button is clicked, we switch out the AppointmentsDayViewLoader component for a CustomerForm component.

We will introduce a state variable named view that defines which component is currently displayed. Initially, it will be set to dayView. When the button is clicked, it will change to addCustomer.

The JSX constructs will initially use a ternary to switch between these two views. Later, we’ll add a third value called addAppointment. When we do that, we’ll “upgrade” our ternary expression to a switch statement.

To get started, follow these steps:

  1. Create a new file, test/App...

Test-driving callback props

In this section, we’ll introduce a new extension function, propsOf, that reaches into a mocked child component and returns the props that were passed to it. We’ll use this to get hold of the onSave callback prop value and invoke it from our test, mimicking what would happen if the real CustomerForm had been submitted.

It’s worth revisiting why this is something we’d like to do. Reaching into a component and calling the prop directly seems complicated. However, the alternative is more complicated and more brittle.

The test we want to write next is the one that asserts that the AppointmentFormLoader component is shown after CustomerForm has been submitted and a new customer has been saved:

it("displays the AppointmentFormLoader after the CustomerForm is submitted", async () => {
  // ...
});

Now, imagine that we wanted to test this without a mocked CustomerForm. We would need to fill in the real...

Making use of callback values

In this section, we’ll introduce a new state variable, customer, that will be set when CustomerForm receives the onSave callback. After that, we’ll do the final transition in our workflow, from addAppointment back to dayView.

Follow these steps:

  1. This time, we’ll check that the new customer ID is passed to AppointmentFormLoader. Remember in the previous section how we gave saveCustomer a customer parameter? We’ll make use of that in this test:
    it("passes the customer to the AppointmentForm", async () => {
      const customer = { id: 123 };
      render(<App />);
      beginAddingCustomerAndAppointment();
      saveCustomer(customer);
      expect(AppointmentFormLoader).toBeRenderedWithProps(
        expect.objectContaining({
          original: expect.objectContaining({
            customer...

Summary

This chapter covered the final TDD technique for you to learn – mocked component callback props. You learned how to get a reference to a component callback using the propsOf extension, as well as how to use a state variable to manage the transitions between different parts of a workflow.

You will have noticed how all the child components in App were mocked out. This is often the case with top-level components, where each child component is a relatively complex, self-contained unit.

In the next part of this book, we’ll apply everything we’ve learned to more complex scenarios. We’ll start by introducing field validation into our CustomerForm component.

Exercises

The following are some exercises for you to try out:

  1. Update your CustomerForm and AppointmentForm tests to use the new builders you’ve created.
  2. Add a test to AppointmentForm that ensures that the customer ID is submitted when the form is submitted.
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 2022Publisher: PacktISBN-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.
undefined
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

Author (1)

author image
Daniel Irvine

Daniel Irvine is a UK-based software consultant. He helps businesses simplify their existing codebases and assists dev teams in improving the quality of their software using eXtreme programming (XP) practices. He has been coaching developers for many years and co-founded the Queer Code London meetup.
Read more about Daniel Irvine