source: frontend/node_modules/eslint-plugin-jest/docs/rules/require-hook.md

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 12 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 4.5 KB
RevLine 
[9af201e]1# Require setup and teardown code to be within a hook (`require-hook`)
2
3Often while writing tests you have some setup work that needs to happen before
4tests run, and you have some finishing work that needs to happen after tests
5run. Jest provides helper functions to handle this.
6
7It's common when writing tests to need to perform setup work that needs to
8happen before tests run, and finishing work after tests run.
9
10Because Jest executes all `describe` handlers in a test file _before_ it
11executes any of the actual tests, it's important to ensure setup and teardown
12work is done inside `before*` and `after*` handlers respectively, rather than
13inside the `describe` blocks.
14
15## Rule details
16
17This rule flags any expression that is either at the toplevel of a test file or
18directly within the body of a `describe`, _except_ for the following:
19
20- `import` statements
21- `const` variables
22- `let` _declarations_, and initializations to `null` or `undefined`
23- Classes
24- Types
25- Calls to the standard Jest globals
26
27This rule flags any function calls within test files that are directly within
28the body of a `describe`, and suggests wrapping them in one of the four
29lifecycle hooks.
30
31Here is a slightly contrived test file showcasing some common cases that would
32be flagged:
33
34```js
35import { database, isCity } from '../database';
36import { Logger } from '../../../src/Logger';
37import { loadCities } from '../api';
38
39jest.mock('../api');
40
41const initializeCityDatabase = () => {
42 database.addCity('Vienna');
43 database.addCity('San Juan');
44 database.addCity('Wellington');
45};
46
47const clearCityDatabase = () => {
48 database.clear();
49};
50
51initializeCityDatabase();
52
53test('that persists cities', () => {
54 expect(database.cities.length).toHaveLength(3);
55});
56
57test('city database has Vienna', () => {
58 expect(isCity('Vienna')).toBeTruthy();
59});
60
61test('city database has San Juan', () => {
62 expect(isCity('San Juan')).toBeTruthy();
63});
64
65describe('when loading cities from the api', () => {
66 let consoleWarnSpy = jest.spyOn(console, 'warn');
67
68 loadCities.mockResolvedValue(['Wellington', 'London']);
69
70 it('does not duplicate cities', async () => {
71 await database.loadCities();
72
73 expect(database.cities).toHaveLength(4);
74 });
75
76 it('logs any duplicates', async () => {
77 await database.loadCities();
78
79 expect(consoleWarnSpy).toHaveBeenCalledWith(
80 'Ignored duplicate cities: Wellington',
81 );
82 });
83});
84
85clearCityDatabase();
86```
87
88Here is the same slightly contrived test file showcasing the same common cases
89but in ways that would be **not** flagged:
90
91```js
92import { database, isCity } from '../database';
93import { Logger } from '../../../src/Logger';
94import { loadCities } from '../api';
95
96jest.mock('../api');
97
98const initializeCityDatabase = () => {
99 database.addCity('Vienna');
100 database.addCity('San Juan');
101 database.addCity('Wellington');
102};
103
104const clearCityDatabase = () => {
105 database.clear();
106};
107
108beforeEach(() => {
109 initializeCityDatabase();
110});
111
112test('that persists cities', () => {
113 expect(database.cities.length).toHaveLength(3);
114});
115
116test('city database has Vienna', () => {
117 expect(isCity('Vienna')).toBeTruthy();
118});
119
120test('city database has San Juan', () => {
121 expect(isCity('San Juan')).toBeTruthy();
122});
123
124describe('when loading cities from the api', () => {
125 let consoleWarnSpy;
126
127 beforeEach(() => {
128 consoleWarnSpy = jest.spyOn(console, 'warn');
129 loadCities.mockResolvedValue(['Wellington', 'London']);
130 });
131
132 it('does not duplicate cities', async () => {
133 await database.loadCities();
134
135 expect(database.cities).toHaveLength(4);
136 });
137
138 it('logs any duplicates', async () => {
139 await database.loadCities();
140
141 expect(consoleWarnSpy).toHaveBeenCalledWith(
142 'Ignored duplicate cities: Wellington',
143 );
144 });
145});
146
147afterEach(() => {
148 clearCityDatabase();
149});
150```
151
152## Options
153
154If there are methods that you want to call outside of hooks and tests, you can
155mark them as allowed using the `allowedFunctionCalls` option.
156
157```json
158{
159 "jest/require-hook": [
160 "error",
161 {
162 "allowedFunctionCalls": ["enableAutoDestroy"]
163 }
164 ]
165}
166```
167
168Examples of **correct** code when using
169`{ "allowedFunctionCalls": ["enableAutoDestroy"] }` option:
170
171```js
172/* eslint jest/require-hook: ["error", { "allowedFunctionCalls": ["enableAutoDestroy"] }] */
173
174import { enableAutoDestroy, mount } from '@vue/test-utils';
175import { initDatabase, tearDownDatabase } from './databaseUtils';
176
177enableAutoDestroy(afterEach);
178
179beforeEach(initDatabase);
180afterEach(tearDownDatabase);
181
182describe('Foo', () => {
183 test('always returns 42', () => {
184 expect(global.getAnswer()).toBe(42);
185 });
186});
187```
Note: See TracBrowser for help on using the repository browser.