Testing Lab 5: Container Components
Objectives
- Test Setup
- Test the Loading Indicator Displays
- Test the Projects Display
- Test the More Button Displays
- Test the Error Displays
Steps
Test Setup
- Create the file - src\projects\__tests__\ProjectsPage-test.js.
- Add the setup code below to test the component. - src\projects\__tests__\ProjectsPage-test.js- import React from 'react';
 import { MemoryRouter } from 'react-router-dom';
 import { Provider } from 'react-redux';
 import { store } from '../../state';
 import ProjectsPage from '../ProjectsPage';
 import {
 render,
 screen,
 waitForElementToBeRemoved,
 } from '@testing-library/react';
 describe('<ProjectsPage />', () => {
 function renderComponent() {
 render(
 <Provider store={store}>
 <MemoryRouter>
 <ProjectsPage />
 </MemoryRouter>
 </Provider>
 );
 }
 test('should render without crashing', () => {
 renderComponent();
 expect(screen).toBeDefined();
 });
 });
- Verify the initial test passed. - PASS src/projects/__tests__/ProjectsPage-test.js- ! Check to make sure the - delayfunction used to delay the backend query and display the loading indicator has been removed in- projectAPI.js. The delay call causes the- mswlibrary to throw an error.
Test the Loading Indicator Displays
- Test that the loading indicator displays when the component initially renders. - src\projects\__tests__\ProjectsPage-test.js- import React from 'react';
 import { MemoryRouter } from 'react-router-dom';
 import { Provider } from 'react-redux';
 import { store } from '../../state';
 import ProjectsPage from '../ProjectsPage';
 import {
 render,
 screen,
 waitForElementToBeRemoved,
 } from '@testing-library/react';
 describe('<ProjectsPage />', () => {
 function renderComponent() {
 render(
 <Provider store={store}>
 <MemoryRouter>
 <ProjectsPage />
 </MemoryRouter>
 </Provider>
 );
 }
 ...
 + test('should display loading', () => {
 + renderComponent();
 + expect(screen.getByText(/loading/i)).toBeInTheDocument();
 + });
 });
- Verify the test passed. - PASS src/projects/__tests__/ProjectsPage-test.js
Test the Projects Display
- Open a - command prompt(Windows) or- terminal(Mac).
- Change the current directory to - code\keeptrack.
- Run one of the following sets of commands to install - Mock Service Workerto mock the HTTP requests.- $ npm install msw@1 --save-dev
 # or
 $ yarn add msw@1 --dev
- Export the url used in the component from the - projectAPI.jsfile.- src\projects\projectAPI.js- import { Project } from './Project';
 const baseUrl = 'http://localhost:4000';
 - const url = `${baseUrl}/projects`;
 + export const url = `${baseUrl}/projects`;
 ...
- Add the setup code to mock the requests. - src\projects\__tests__\ProjectsPage-test.js- import React from 'react';
 import { MemoryRouter } from 'react-router-dom';
 import { MOCK_PROJECTS } from '../MockProjects';
 import { Provider } from 'react-redux';
 import { store } from '../../state';
 import ProjectsPage from '../ProjectsPage';
 import {
 render,
 screen,
 waitForElementToBeRemoved,
 } from '@testing-library/react';
 + import { rest } from 'msw';
 + import { setupServer } from 'msw/node';
 + import { url as projectsUrl } from '../projectAPI';
 + import { MOCK_PROJECTS } from '../MockProjects';
 + // declare which API requests to mock
 + const server = setupServer(
 + // capture "GET http://localhost:3000/projects" requests
 + rest.get(projectsUrl, (req, res, ctx) => {
 + // respond using a mocked JSON body
 + return res(ctx.json(MOCK_PROJECTS));
 + })
 + );
 describe('<ProjectsPage />', () => {
 function renderComponent() {
 render(
 <Provider store={store}>
 <MemoryRouter>
 <ProjectsPage />
 </MemoryRouter>
 </Provider>
 );
 }
 + beforeAll(() => server.listen());
 + afterEach(() => server.resetHandlers());
 + afterAll(() => server.close());
 test('should render without crashing', () => {
 renderComponent();
 expect(screen).toBeDefined();
 });
 test('should display loading', () => {
 renderComponent();
 expect(screen.getByText(/loading/i)).toBeInTheDocument();
 });
 });
- Test that the projects display after the mocked data is returned. - src\projects\__tests__\ProjectsPage-test.js- ...
 describe('<ProjectsPage />', () => {
 function renderComponent() {
 render(
 <Provider store={store}>
 <MemoryRouter>
 <ProjectsPage />
 </MemoryRouter>
 </Provider>
 );
 }
 beforeAll(() => server.listen());
 afterEach(() => server.resetHandlers());
 afterAll(() => server.close());
 ...
 + test('should display projects', async () => {
 + renderComponent();
 + expect(await screen.findAllByRole('img')).toHaveLength(
 + MOCK_PROJECTS.length
 + );
 + });
 });
- Verify the test passed. - PASS src/projects/__tests__/ProjectsPage-test.js
Test the More Button Displays
- Test that the More button displays after the projects have loaded. - src\projects\__tests__\ProjectsPage-test.js- ...
 import {
 render,
 screen,
 waitForElementToBeRemoved,
 } from '@testing-library/react';
 ...
 describe('<ProjectsPage />', () => {
 ...
 + test('should display more button', async () => {
 + renderComponent();
 + expect(
 + await screen.findByRole('button', { name: /more/i })
 + ).toBeInTheDocument();
 + });
 +
 + // this tests the same as the last test but demonstrates
 + // what find* methods are doing
 + test('should display more button with get', async () => {
 + renderComponent();
 + await waitForElementToBeRemoved(() => screen.queryByText(/loading/i));
 + expect(screen.getByRole('button', { name: /more/i })).toBeInTheDocument();
 + });
 });
- Verify the test passed. - PASS src/projects/__tests__/ProjectsPage-test.js
Test the Error Displays
- Test that a custom error displays when a server error is returned. - src\projects\__tests__\ProjectsPage-test.js- ...
 import {
 render,
 screen,
 waitForElementToBeRemoved,
 } from '@testing-library/react';
 ...
 describe('<ProjectsPage />', () => {
 ...
 + test('should display custom error on server error', async () => {
 + server.use(
 + rest.get(projectsUrl, (req, res, ctx) => {
 + return res(ctx.status(500, 'Server error'));
 + })
 + );
 + renderComponent();
 +
 + expect(
 + await screen.findByText(/There was an error retrieving the project(s)./i)
 + ).toBeInTheDocument();
 + });
 });
- Verify the test passed. - PASS src/projects/__tests__/ProjectsPage-test.js