Custom Jest matchers for testing React components with Enzyme
npx @tessl/cli install tessl/npm-jest-enzyme@7.1.00
# Jest Enzyme
1
2
Jest Enzyme provides custom Jest matchers for testing React components with Enzyme. It extends Jest's assertion capabilities with enzyme-specific matchers, making React component testing more intuitive and readable by providing domain-specific assertions that understand Enzyme wrapper objects.
3
4
## Package Information
5
6
- **Package Name**: jest-enzyme
7
- **Package Type**: npm
8
- **Language**: JavaScript/TypeScript
9
- **Installation**: `npm install jest-enzyme`
10
- **Peer Dependencies**: enzyme (>=3.4.0), jest (>=22.0.0)
11
12
## Core Imports
13
14
The package functions as a Jest setupFilesAfterEnv script and extends Jest's expect function automatically:
15
16
```javascript
17
// package.json
18
"jest": {
19
"setupFilesAfterEnv": ["./node_modules/jest-enzyme/lib/index.js"]
20
}
21
```
22
23
For TypeScript support:
24
25
```typescript
26
// src/setupTests.ts
27
import 'jest-enzyme';
28
```
29
30
## Basic Usage
31
32
```javascript
33
import React from 'react';
34
import { mount } from 'enzyme';
35
36
function MyComponent({ checked, disabled, className }) {
37
return (
38
<div className={className}>
39
<input type="checkbox" defaultChecked={checked} disabled={disabled} />
40
<span>Hello World</span>
41
</div>
42
);
43
}
44
45
const wrapper = mount(<MyComponent checked={true} className="test-class" />);
46
47
// Use jest-enzyme matchers
48
expect(wrapper.find('input')).toBeChecked();
49
expect(wrapper.find('input')).not.toBeDisabled();
50
expect(wrapper).toHaveClassName('test-class');
51
expect(wrapper.find('span')).toHaveText('Hello World');
52
```
53
54
## Architecture
55
56
Jest Enzyme is built around several key components:
57
58
- **Setup Script**: Automatically configures enzyme-to-json serializer and extends Jest's expect
59
- **Matcher Wrapping**: Wraps enzyme-matchers with Jest-specific error formatting and contextual information
60
- **Snapshot Serializer**: Integrates enzyme-to-json for clean, readable enzyme wrapper snapshots
61
- **TypeScript Integration**: Complete type definitions for all matchers in Jest's Matchers interface
62
- **Environment Integration**: Optional integration with jest-environment-enzyme for enzyme globals
63
64
## Capabilities
65
66
### Element State Matchers
67
68
Matchers for testing element state conditions like checked, disabled, and existence.
69
70
```javascript { .api }
71
// Assert that input element is checked
72
expect(wrapper).toBeChecked(): void;
73
74
// Assert that element is disabled
75
expect(wrapper).toBeDisabled(): void;
76
77
// Assert that component renders null or false
78
expect(wrapper).toBeEmptyRender(): void;
79
80
// Assert that element exists in the wrapper
81
expect(wrapper).toExist(): void;
82
```
83
84
**Usage Examples:**
85
86
```javascript
87
const wrapper = mount(
88
<div>
89
<input id="checked" defaultChecked />
90
<input id="disabled" disabled />
91
<input id="normal" />
92
</div>
93
);
94
95
expect(wrapper.find('#checked')).toBeChecked();
96
expect(wrapper.find('#disabled')).toBeDisabled();
97
expect(wrapper.find('#normal')).toExist();
98
expect(wrapper.find('#nonexistent')).not.toExist();
99
```
100
101
### Element Content Matchers
102
103
Matchers for testing element content including text, HTML, and CSS classes.
104
105
```javascript { .api }
106
// Assert element has specific CSS class
107
expect(wrapper).toHaveClassName(className: string): void;
108
109
// Assert component has specific display name
110
expect(wrapper).toHaveDisplayName(tagName: string): void;
111
112
// Assert element has specific HTML content
113
expect(wrapper).toHaveHTML(html: string): void;
114
115
// Assert element has specific tag name (deprecated - use toHaveDisplayName)
116
expect(wrapper).toHaveTagName(tagName: string): void;
117
118
// Assert element has specific text content (exact match)
119
expect(wrapper).toHaveText(text: string): void;
120
121
// Assert element includes specific text (partial match)
122
expect(wrapper).toIncludeText(text: string): void;
123
124
// Assert form element has specific value
125
expect(wrapper).toHaveValue(value: any): void;
126
```
127
128
**Usage Examples:**
129
130
```javascript
131
const wrapper = mount(
132
<div className="container active">
133
<span id="greeting">Hello World</span>
134
<input type="text" defaultValue="test input" />
135
</div>
136
);
137
138
expect(wrapper).toHaveClassName('container');
139
expect(wrapper).toHaveClassName('active');
140
expect(wrapper.find('#greeting')).toHaveText('Hello World');
141
expect(wrapper.find('#greeting')).toIncludeText('Hello');
142
expect(wrapper.find('input')).toHaveValue('test input');
143
expect(wrapper.find('#greeting')).toHaveHTML('<span id="greeting">Hello World</span>');
144
```
145
146
### Element Properties Matchers
147
148
Matchers for testing component props, state, styles, and refs.
149
150
```javascript { .api }
151
// Assert element has specific prop with optional value check
152
expect(wrapper).toHaveProp(propKey: object|string, propValue?: any): void;
153
154
// Assert element has specific ref
155
expect(wrapper).toHaveRef(refName: string): void;
156
157
// Assert component has specific state with optional value check
158
expect(wrapper).toHaveState(stateKey: object|string, stateValue?: any): void;
159
160
// Assert element has specific CSS style property
161
expect(wrapper).toHaveStyle(styleKey: object|string, styleValue?: any): void;
162
```
163
164
**Usage Examples:**
165
166
```javascript
167
function TestComponent({ title, count }) {
168
const [active, setActive] = React.useState(true);
169
return <div ref="container" style={{ color: 'red' }} title={title} />;
170
}
171
172
const wrapper = mount(<TestComponent title="Test" count={5} />);
173
174
expect(wrapper).toHaveProp('title', 'Test');
175
expect(wrapper).toHaveProp('count');
176
expect(wrapper).toHaveProp({ title: 'Test', count: 5 });
177
expect(wrapper).toHaveState('active', true);
178
expect(wrapper).toHaveState({ active: true });
179
expect(wrapper).toHaveStyle('color', 'red');
180
expect(wrapper).toHaveStyle({ color: 'red' });
181
expect(wrapper).toHaveRef('container');
182
```
183
184
### Element Matching Matchers
185
186
Matchers for testing element presence and React element matching.
187
188
```javascript { .api }
189
// Assert wrapper contains at least one element matching selector
190
expect(wrapper).toContainMatchingElement(selector: string): void;
191
192
// Assert wrapper contains exactly n elements matching selector
193
expect(wrapper).toContainMatchingElements(n: number, selector: string): void;
194
195
// Assert wrapper contains exactly one element matching selector
196
expect(wrapper).toContainExactlyOneMatchingElement(selector: string): void;
197
198
// Assert wrapper contains specific React element
199
expect(wrapper).toContainReact(component: React.ReactElement<any>): void;
200
201
// Assert wrapper matches specific React element structure
202
expect(wrapper).toMatchElement(
203
element: React.ReactElement<any>,
204
options?: ToMatchElementOptions
205
): void;
206
207
// Assert element matches CSS selector
208
expect(wrapper).toMatchSelector(selector: string): void;
209
```
210
211
**Usage Examples:**
212
213
```javascript
214
function User({ id, name }) {
215
return <span className={`user-${id}`}>{name}</span>;
216
}
217
218
const wrapper = mount(
219
<div>
220
<User id={1} name="Alice" />
221
<User id={2} name="Bob" />
222
<span className="info">Info text</span>
223
</div>
224
);
225
226
expect(wrapper).toContainMatchingElement('.user-1');
227
expect(wrapper).toContainMatchingElements(2, 'User');
228
expect(wrapper).toContainExactlyOneMatchingElement('.info');
229
expect(wrapper).toContainReact(<User id={1} name="Alice" />);
230
expect(wrapper.find('User').first()).toMatchElement(<User />);
231
expect(wrapper.find('.user-1')).toMatchSelector('.user-1');
232
```
233
234
## Types
235
236
```typescript { .api }
237
declare namespace jest {
238
interface ToMatchElementOptions {
239
ignoreProps?: boolean;
240
}
241
242
interface Matchers<R, T> {
243
// Element State Matchers
244
toBeChecked(): void;
245
toBeDisabled(): void;
246
toBeEmptyRender(): void;
247
toExist(): void;
248
249
// Element Content Matchers
250
toHaveClassName(className: string): void;
251
toHaveDisplayName(tagName: string): void;
252
toHaveHTML(html: string): void;
253
toHaveTagName(tagName: string): void;
254
toHaveText(text: string): void;
255
toIncludeText(text: string): void;
256
toHaveValue(value: any): void;
257
258
// Element Properties Matchers
259
toHaveProp(propKey: object|string, propValue?: any): void;
260
toHaveRef(refName: string): void;
261
toHaveState(stateKey: object|string, stateValue?: any): void;
262
toHaveStyle(styleKey: object|string, styleValue?: any): void;
263
264
// Element Matching Matchers
265
toContainMatchingElement(selector: string): void;
266
toContainMatchingElements(n: number, selector: string): void;
267
toContainExactlyOneMatchingElement(selector: string): void;
268
toContainReact(component: React.ReactElement<any>): void;
269
toMatchElement(
270
element: React.ReactElement<any>,
271
options?: ToMatchElementOptions
272
): void;
273
toMatchSelector(selector: string): void;
274
}
275
}
276
```
277
278
## Setup Methods
279
280
Jest Enzyme provides multiple setup options to integrate with your testing environment:
281
282
### Method 1: jest-environment-enzyme (Recommended)
283
284
The recommended approach uses the dedicated Jest environment that automatically configures enzyme globals and jest-enzyme matchers:
285
286
```javascript
287
// package.json
288
"jest": {
289
"testEnvironment": "enzyme",
290
"testEnvironmentOptions": {
291
"enzymeAdapter": "react16"
292
}
293
}
294
```
295
296
### Method 2: setupFilesAfterEnv
297
298
For projects that prefer to configure setup files manually:
299
300
```javascript
301
// package.json
302
"jest": {
303
"setupFilesAfterEnv": ["./node_modules/jest-enzyme/lib/index.js"]
304
}
305
```
306
307
### Method 3: Create React App
308
309
For Create React App projects, add the import to your test setup file:
310
311
```javascript
312
// src/setupTests.js
313
import 'jest-enzyme';
314
```
315
316
### Method 4: TypeScript Projects
317
318
For TypeScript projects, create a setup file and configure Jest to use it:
319
320
```typescript
321
// src/setupTests.ts
322
import 'jest-enzyme';
323
```
324
325
```javascript
326
// package.json
327
"jest": {
328
"setupFilesAfterEnv": ["./src/setupTests.ts"]
329
}
330
```
331
332
## Rendering Strategy Compatibility
333
334
Different matchers support different Enzyme rendering methods:
335
336
| Matcher | render | mount | shallow |
337
|---------|--------|-------|---------|
338
| toBeChecked | no | yes | yes |
339
| toBeDisabled | no | yes | yes |
340
| toBeEmptyRender | no | yes | yes |
341
| toExist | no | yes | yes |
342
| toContainMatchingElement | no | yes | yes |
343
| toContainMatchingElements | no | yes | yes |
344
| toContainExactlyOneMatchingElement | no | yes | yes |
345
| toContainReact | no | yes | yes |
346
| toHaveClassName | no | yes | yes |
347
| toHaveDisplayName | no | yes | yes |
348
| toHaveHTML | no | yes | yes |
349
| toHaveProp | no | yes | yes |
350
| toHaveRef | no | yes | yes |
351
| toHaveState | no | yes | yes |
352
| toHaveStyle | no | yes | yes |
353
| toHaveTagName | no | yes | yes |
354
| toHaveText | no | yes | yes |
355
| toIncludeText | no | yes | yes |
356
| toHaveValue | no | yes | yes |
357
| toMatchElement | no | yes | yes |
358
| toMatchSelector | no | yes | yes |
359
360
## Error Handling
361
362
All matchers provide:
363
- Pass/fail boolean results
364
- Descriptive error messages for failures
365
- Negated error messages for `.not` usage
366
- Contextual information including actual HTML output
367
- Color-coded expected/received values using Jest's utils