TDD Lifecycle Revisited

Continue writing tests, and begin fixing them with production code.

Our first unit test

Once we have our first integration test failing, it is time to write our first unit tests.

Unit tests are designed to test system components in isolation.

To make isolation of system components possible, we will create multiple components: TaskInput to input new tasks and TaskList to display a list of tasks.

Create a folder called components in src and create a file called TaskInput.test.js. This file will hold tests for the TaskInput component, which we have yet have to create.

Now, we will learn some more Jest functions. If you recall, we defined our integration tests with the test function. This is also possible for unit tests. But we are going to learn one more approach, and then you can decide whichever approach you can prefer.

Another way of organizing tests is by using the describe and it functions. describe is a function to group multiple tests together, and it is the same as the test function. Here is how they could be used:

describe('<SomeComponent />', () => {
  it('renders', () => {...});
  it('shows label', () => {...});
  it('handles input', () => {...});
});

The big advantage of this approach is readability. This snippet is very clear and easy to read. And when any of these tests fail, Jest will provide a helpful message, letting you know exactly what went wrong.

Now, you can write the structure for your first test. First, we will test that TaskInput renders an input element:

describe('<TaskInput />', () => {
    it('renders an input', () => {

    });
});

Now, how do we actually test that input is rendered? For this, @testing-library is used.

@testing-library

This is a family of libraries used to unit test web apps. The React version of it is called @testing-library/react. This is included by default in apps created with create-react-app, so there is no additional setup necessary.

This library exports many things, but we are interested mostly in render and screen.

  • render is a function that renders. You use it like this: render(<div />).
  • screen is an object that represents a browser screen. Whatever you render with render is made available from screen. You can query stuff from it like this: screen.queryByText(...).

To use these, you must import them. We will also import React as it is needed for the JSX syntax:

import React from 'react'

import TaskInput from './TaskInput';
import {render, screen} from '@testing-library/react'

Now we can fill in the test body:

describe('<TaskInput />', () => {
    it('renders an input', () => {
        render(<TaskInput />);
        expect(screen.queryByPlaceholderText('Enter new task')).toBeInTheDocument();
    });
});

First, we render the component. It does not have props so far, so do not worry about them. Next, we try to query ByPlaceholderText to get the input element. Lastly, we assert that it is inTheDocument. Here is the entire project so far:

Create a free account to view this lesson.

By signing up, you agree to Educative's Terms of Service and Privacy Policy