React Code Examples

For “No, Stop Mocks”

We’re working with the same hypothetical from the mockist React example, only this time we’re approaching that page from the parent ‘App’ component.

This example shows how, ironically, trying to avoid mocks leads to needing a lot of I/O mocks to stub out the edges of our application.

It also contains a world of ‘todos’. This is for the basic reason that you’d die of boredom reading all the I/O mocks and protracted UX steps. That is if I survived the tedium of writing them in the first place. 😅

import { render, screen, waitForElementToBeRemoved } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { rest } from 'msw';
import { setupServer } from 'msw/node';
import React from 'react';

import { App } from './index';

const mockServer = setupServer();

describe('when logging in succeeds', () => {
  beforeEach(() => {
    mockServer.use(
      rest.post('/login', (_, response, context) =>
        response(context.json({ token: 'some-login-token' })),
      ),
    );

    mockServer.use(
      rest.get('/analytics', (_, response, context) =>
        response(
          context.json({ session: 'some-session-value', gaCode: 'some-google-related-whatever' }),
        ),
      ),
    );

    mockServer.use(
      rest.get('/latest-user-news', (_, response, context) => response(context.json([]))),
    );

    mockServer.use(
      rest.get('/notifications', (_, response, context) =>
        response(
          context.json([
            {
              title: 'Change your password in the next 3 days',
              content:
                'In adherence with our security policy, your password will expire in 3 days. Failure to do so may leave you locked out of your account. Click the following link to reset your password now.',
              link: '/faqs/changing-your-password',
            },
          ]),
        ),
      ),
    );
  });

  describe('when there are users', () => {
    mockServer.use(
      rest.get('/users', (_, response, context) =>
        response(
          context.json([
            {
              name: 'Joe',
              age: 24,
              id: 'some-id-for-joe',
              email: 'joe@joe.org',
              bio: 'Joe is a big fan of the out doors and having to mock out lots of data that he did not actually need from a REST endpoint.',
              meta: {
                created: '2020-01-01',
                lastOnline: '2020-18-01',
                isAdmin: false,
                lovesBroccoli: true,
              },
            },
            {
              name: 'Claire',
              age: 36,
              id: 'some-id-for-claire',
              email: 'claire@claire.dev',
              bio: 'Claire is an enigma.',
              meta: {
                created: '2020-01-01',
                lastOnline: '2020-18-01',
                isAdmin: true,
                lovesBroccoli: true,
              },
            },
          ]),
        ),
      ),
    );

    it('displays the name and age of each user', async () => {
      render(<App />);

      await waitForElementToBeRemoved(() => screen.findByText('Loading...'));

      await userEvent.type(screen.getByLabelText('Name'), 'some-login@works.com');
      await userEvent.type(screen.getByLabelText('Password'), 'myL0v3lyPassW0rd');
      await userEvent.click(screen.getByRole('button', { name: 'Log in' }));

      await waitForElementToBeRemoved(() => screen.findByText('Logging in...'));

      await userEvent.click(screen.getByRole('link', { name: 'View all users' }));

      await waitForElementToBeRemoved(() => screen.findByText('Loading...'));

      expect(screen.getByRole('cell', { name: 'Joe' })).toBeInTheDocument();
      expect(screen.getByRole('cell', { name: '24' })).toBeInTheDocument();

      expect(screen.getByRole('cell', { name: 'Claire' })).toBeInTheDocument();
      expect(screen.getByRole('cell', { name: '36' })).toBeInTheDocument();
    });

    it.todo('when deleting a user is pending');

    it.todo('when deleting a user succeeds');

    it.todo('when deleting a user fails');
  });

  it.todo('when there are no users');
});

it.todo('when logging in fails');

Back to the main article