For “Nonstop Mocks”
The following is a mock based test for a hypothetical ‘UsersPage’. Imagine a webpage where you can see the names and ages of users of your application, with the option to delete them if you wish.
Notice how the test makes use of spies and mocks to replace internals of the unit under test (‘UsersPage’) and how the assertions are all based around interactions with these mocks.
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';
import * as TableModule from './Table';
import * as NoUsersModule from './NoUsers';
import * as userService from '../services/user';
import { UsersPage } from './UsersPage';
describe('when there are users', () => {
beforeEach(() => {
jest.spyOn(userService, 'getUsers').mockResolvedValue([
{
name: 'Joe',
age: 24,
id: 'some-id-for-joe',
email: 'joe@joe.org',
bio: 'Something about Joe here.',
meta: {
created: '2020-01-01',
lastOnline: '2020-18-01',
isAdmin: false,
lovesBroccoli: true,
},
},
]);
});
it('mounts the Table component', () => {
const Table = jest.spyOn(TableModule, 'Table');
render(<UsersPage />);
expect(Table).toHaveBeenCalledWith(
expect.objectContaining({
items: [{ name: 'Joe', age: 24 }],
}),
expect.anything(),
);
});
it('calls "deleteUser" on the users service', async () => {
const deleteMock = jest.spyOn(userService, 'deleteUser').mockResolvedValue({
name: 'Joe',
age: 24,
email: 'joe@joe.org',
bio: 'Something about Joe here.',
meta: {
created: '2020-01-01',
lastOnline: '2020-18-01',
isAdmin: false,
lovesBroccoli: true,
},
});
render(<UsersPage />);
await userEvent.click(screen.getByRole('button', { name: 'Delete Joe' }));
expect(deleteMock).toHaveBeenCalledWith({ id: 'some-id-for-joe' });
});
});
describe('when there are no users', () => {
beforeEach(() => {
jest.spyOn(userService, 'getUsers').mockResolvedValue([]);
});
it('mounts the NoUsers component', () => {
const NoUsers = jest.spyOn(NoUsersModule, 'NoUsers');
render(<UsersPage />);
expect(NoUsers).toHaveBeenCalled();
});
});