React Wiring Library

React Wiring Library

  • Docs
  • API
  • GitHub

›Basic Tutorials

Introduction

  • Getting Started

Basic Tutorials

  • Prepping Components
  • Basic Wiring Structure
  • Building Readable Snapshots
  • Testing Interactions

Advanced Tutorials

  • Using Extend To Make Tests DRY

API Reference

  • getRender
  • Wiring Tree
  • Wiring Node
  • Abstract Wiring Node
  • find{childNode}

Testing Interactions

With our serializers in place, we can actually test. Every line of our tests should be one the following three things.

  1. Calling find{childNode} helpers to get access to a given element.
  2. Calling returned helpers to interact with elements.
  3. Calling toMatchSnapshot to assert the correct behavior.

Review

To review, let's look at where we were with our test.

TodoList.test.js

describe('TodoList', () => {
  test('should render a list of todos', async () => {
    const {findTodoList, serialize} = render(
      <TodoList
        todos={[
          {
            name: 'Todo One',
          },
          {
            name: 'Todo Two',
          },
        ]}
      />,
    )
    const {todoList} = await findTodoList()
    serialize(todoList)
  })
})

Testing initial render

To start, let's confirm the initial render. Luckily, we've pretty much got everything in place to do that already. All we need to do is switch from using serialize to actually calling toMatchSnapshot

  test('should render a list of todos', async () => {
    ...
    const {todoList} = await findTodoList()
    expect(todoList).toMatchSnapshot('on initial render');
  })

The only detail of note here is that you should always pass a title into toMatchSnapshot. When tests fail, this title makes it easier to figure out which snapshot is failing.

If we run the test, we'll see that a snapshot that looks like this.

exports[`TodoList should render a list of todos: on initial render 1`] = `
-◻️ Todo One
-◻️ Todo Two"
`

On the initial render we're expecting the TodoList to have unchecked checkboxes alongside the passed in names. Everything looks right in the snapshot, so we can move on.

The only other functionality we care about is the ability toggle the completion of a Todo.

Query for the first todo

For us to be able to click on an individual Todo we need to query for it.

    ...
    const {todoList, findTodo} = await findTodoList()

Because todo is a child of todoList, calling findTodoList will return findTodo, which we can then use to query for a single todo. Before we move on to how that works, let's review what the wiring for todo looks like.

Todo wiring

todo:  {
  isMultiple: true,
  findValue: 'todo',
  serialize: (val, {checkBoxString}) => {
    return `${checkBoxString}${val ? val.textContent : ''}$`
  },
  children: {
    checkbox: {
      findValue: 'checkbox',
      serialize: val => (val.checked ? '☑️' : '◻️'),
    },
  },
}

Because todo is an isMultiple node we need to actually tell findTodo which of the multiple todos it found to return.

The easiest way to do this is to just specify the index of the item you're interested in.

    ...
    const {todoList, findTodo} = await findTodoList()
    await findTodo({ index: 0 })

If this function runs successfully without throwing an error, we know everything was wired together correctly and we're finding the todo in question.

Clicking a todo

The core model of react-testing-library and by extension react-wiring-library is to call helpers, and get back new, more specific helpers for interacting with a specific element. In keeping with that, we're going to call a function to get down to the actual checkbox, and then call a helper to click on it.

    ...
    const {todoList, findTodo} = await findTodoList()
    expect(todoList).toMatchSnapshot('on initial render');
    const { findCheckbox } = await findTodo({ index: 0 })
    const { click } = await findCheckbox();
    click();
    expect(todoList).toMatchSnapshot('after clicking first todo');

The process for going from the the todo to its checkbox shouldn't be super surprising at this point. checkbox is a child of todo so findCheckbox gets returned from findTodo, which then returns click so we can click the checkbox.

exports[
  `TodoList should render a list of todos: after clicking first todo 1`
] = `
-☑️
-◻️ Todo Two"
`

Great! This is exactly what we'd expect. The checkbox is checked and the name for the checked todo no longer displays.

Source Code

TodoList.test.js

describe('TodoList', () => {
  test('should render a list of todos', async () => {
    const {findTodoList, serialize} = render(
      <TodoList
        todos={[
          {
            name: 'Todo One',
          },
          {
            name: 'Todo Two',
          },
        ]}
      />,
    )
    const {todoList, findTodo} = await findTodoList()
    expect(todoList).toMatchSnapshot('on initial render')
    const {findCheckbox} = await findTodo({index: 0})
    const {click} = await findCheckbox()
    click()
    expect(todoList).toMatchSnapshot('after clicking first todo')
  })
})

Next Steps

At this point, we've made it through all of the basic steps in the testing process. You should have a pretty clear idea what it takes to start adding react-wiring-library tests to your components.

If you'd like to dig deeper, let's take a look at some ways we can make our tests less repetitive and easier to read.

← Building Readable SnapshotsUsing Extend To Make Tests DRY →
  • Review
  • TodoList.test.js
  • Testing initial render
  • Query for the first todo
    • Todo wiring
  • Clicking a todo
  • Source Code
    • TodoList.test.js
  • Next Steps
React Wiring Library
Docs
Getting StartedBasic TutorialsAPI
More
GitHubStar
Copyright © 2019 Clay Branch