Testing the HomePage component

The final component we are going to implement tests for is the HomePage component. Carry out the following steps to do so:

  1. Let's create a file called HomePage.test.tsx with the following content:
import React from 'react';
import { render, cleanup, waitForElement } from '@testing-library/react';
import { HomePage } from './HomePage';
import { BrowserRouter } from 'react-router-dom';

afterEach(cleanup);

test('When HomePage first rendered, loading indicator should show', () => {
const { getByText } = render(
<BrowserRouter>
<HomePage />
</BrowserRouter>,
);

const loading = getByText('Loading...');
expect(loading).not.toBeNull();
});

The test verifies that a Loading... message appears in the HomePage component when it is first rendered.

There is a problem, though, because the HomePage component expects the history, location, and match props to be passed into it:

  1. We are going to create a mock property and pass this into the history, location, and match props:
test('When HomePage first rendered, loading indicator should show', () => {
let mock: any = jest.fn();
const { getByText } = render(
<BrowserRouter>
<HomePage history={mock} location={mock} match={mock} />
</BrowserRouter>,
);

const loading = getByText('Loading...');
expect(loading).not.toBeNull();
});

We create the mock property using jest.fn(). Now, the test will execute and pass as expected.

  1. Let's implement another test to check that unanswered questions are rendered okay:
test('When HomePage data returned, it should render questions', async () => {
let mock: any = jest.fn();
const { getByText } = render(
<BrowserRouter>
<HomePage history={mock} location={mock} match={mock} />
</BrowserRouter>,
);

await waitForElement(() => getByText('Title1 test'));

const question2TitleText = getByText('Title2 test');
expect(question2TitleText).not.toBeNull();
});

This test is similar to our first test on the HomePage component except that we wait for the first question to render using the waitForElement function from the React Testing Library.

However, the test fails. This is because the HomePage component is making an HTTP request to get the data but there is no REST API to handle the request.

  1. We are going to mock the getUnansweredQuestions function with a Jest mock. Let's add the following code above our test:
jest.mock('./QuestionsData', () => ({
getUnansweredQuestions: jest.fn(() => {
return Promise.resolve([
{
questionId: 1,
title: 'Title1 test',
content: 'Content2 test',
userName: 'User1',
created: new Date(2019, 1, 1),
answers: [],
},
{
questionId: 2,
title: 'Title2 test',
content: 'Content2 test',
userName: 'User2',
created: new Date(2019, 1, 1),
answers: [],
},
]);
}),
}));

test('When HomePage first rendered, loading indicator should show', () => ...

The mock function returns two questions that we use in the test assertions.

Now, the test will pass when it runs.

That completes our component tests. It's worth noting that the tests on the Page and Question components are unit tests, whereas those on the HomePage component are integration tests because the test renders the QuestionList and Question components rather than mocking them out.

As we've seen, tests on components are more challenging to write than tests on pure functions, but the React Testing Library and Jest mocks make life fairly straightforward.

In the next section, we are going to complete our test suite by implementing an end-to-end test.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.119.166.90