0
# Testing Utilities
1
2
Testing utilities for React Native Reanimated provide Jest matchers and helper functions for testing animated components and animations. These utilities enable developers to write comprehensive tests for their animated components with proper assertions for styles and props.
3
4
## Capabilities
5
6
### Test Setup
7
8
Configure Jest testing environment for Reanimated with custom framerate settings.
9
10
```typescript { .api }
11
/**
12
* Sets up Jest testing environment for Reanimated testing
13
* @param framerateConfig - Optional framerate configuration for animations
14
*/
15
function setUpTests(framerateConfig?: { fps?: number }): void;
16
```
17
18
**Usage Examples:**
19
20
```typescript
21
import { setUpTests } from "react-native-reanimated";
22
23
// Basic setup with default 60fps
24
setUpTests();
25
26
// Custom framerate for testing
27
setUpTests({ fps: 30 });
28
29
// In your test setup file (setupTests.js)
30
beforeAll(() => {
31
setUpTests();
32
});
33
```
34
35
### Animation Time Control (Deprecated)
36
37
Legacy functions for controlling animation timing in tests. **Note**: These functions are deprecated in favor of Jest's built-in timer functions.
38
39
```typescript { .api }
40
/**
41
* @deprecated Use jest.advanceTimersByTime directly
42
* Advances animation by specified time in milliseconds
43
* @param time - Time in milliseconds to advance (default: frame time)
44
*/
45
function advanceAnimationByTime(time?: number): void;
46
47
/**
48
* @deprecated Use jest.advanceTimersByTime directly
49
* Advances animation by specified number of frames
50
* @param count - Number of frames to advance
51
*/
52
function advanceAnimationByFrame(count: number): void;
53
54
/**
55
* @deprecated Define your own before/after test hooks
56
* Wraps animation test with fake timers setup and cleanup
57
* @param animationTest - Test function to execute
58
*/
59
function withReanimatedTimer(animationTest: () => void): void;
60
```
61
62
**Usage Examples (Deprecated):**
63
64
```typescript
65
import {
66
advanceAnimationByTime,
67
advanceAnimationByFrame,
68
withReanimatedTimer
69
} from "react-native-reanimated";
70
71
// Deprecated - use jest.advanceTimersByTime(16) instead
72
advanceAnimationByTime(16);
73
74
// Deprecated - use jest.advanceTimersByTime(count * 16) instead
75
advanceAnimationByFrame(5);
76
77
// Deprecated - set up your own before/after hooks
78
withReanimatedTimer(() => {
79
// Your animation test code
80
});
81
```
82
83
**Recommended Modern Approach:**
84
85
```typescript
86
describe('Animation Tests', () => {
87
beforeEach(() => {
88
jest.useFakeTimers();
89
});
90
91
afterEach(() => {
92
jest.runOnlyPendingTimers();
93
jest.useRealTimers();
94
});
95
96
it('should animate properly', () => {
97
// Start animation
98
triggerAnimation();
99
100
// Advance by 16ms (one frame at 60fps)
101
jest.advanceTimersByTime(16);
102
103
// Your assertions
104
expect(component).toHaveAnimatedStyle({ opacity: 0.5 });
105
});
106
});
107
```
108
109
### Animated Style Inspection
110
111
Extract animated styles from components for testing purposes.
112
113
```typescript { .api }
114
/**
115
* Gets the current animated style from a test component
116
* @param component - React test instance of an animated component
117
* @returns Current animated style object
118
*/
119
function getAnimatedStyle(component: ReactTestInstance): DefaultStyle;
120
```
121
122
**Usage Examples:**
123
124
```typescript
125
import { getAnimatedStyle } from "react-native-reanimated";
126
import { render } from "@testing-library/react-native";
127
128
const MyAnimatedComponent = () => {
129
const opacity = useSharedValue(1);
130
const animatedStyle = useAnimatedStyle(() => ({
131
opacity: opacity.value,
132
}));
133
134
return <Animated.View style={animatedStyle} testID="animated-view" />;
135
};
136
137
it('should have correct animated style', () => {
138
const { getByTestId } = render(<MyAnimatedComponent />);
139
const component = getByTestId('animated-view');
140
141
const style = getAnimatedStyle(component);
142
expect(style.opacity).toBe(1);
143
});
144
```
145
146
## Jest Matchers
147
148
### toHaveAnimatedStyle
149
150
Jest matcher for asserting animated styles on components.
151
152
```typescript { .api }
153
// Jest matcher interface
154
interface Matchers<R> {
155
toHaveAnimatedStyle(
156
style: Record<string, unknown> | Record<string, unknown>[],
157
config?: { shouldMatchAllProps?: boolean }
158
): R;
159
}
160
```
161
162
**Usage Examples:**
163
164
```typescript
165
import Animated, { useSharedValue, useAnimatedStyle } from "react-native-reanimated";
166
167
const AnimatedComponent = ({ testID }: { testID: string }) => {
168
const scale = useSharedValue(1);
169
const animatedStyle = useAnimatedStyle(() => ({
170
transform: [{ scale: scale.value }],
171
opacity: 0.8,
172
}));
173
174
return <Animated.View style={animatedStyle} testID={testID} />;
175
};
176
177
describe('Animated Style Tests', () => {
178
it('should have correct animated style', () => {
179
const { getByTestId } = render(<AnimatedComponent testID="test" />);
180
const component = getByTestId('test');
181
182
// Basic style assertion
183
expect(component).toHaveAnimatedStyle({
184
opacity: 0.8,
185
});
186
187
// Transform assertion
188
expect(component).toHaveAnimatedStyle({
189
transform: [{ scale: 1 }],
190
});
191
192
// Multiple properties
193
expect(component).toHaveAnimatedStyle({
194
opacity: 0.8,
195
transform: [{ scale: 1 }],
196
});
197
198
// Match all properties exactly
199
expect(component).toHaveAnimatedStyle({
200
opacity: 0.8,
201
transform: [{ scale: 1 }],
202
}, { shouldMatchAllProps: true });
203
});
204
});
205
```
206
207
### toHaveAnimatedProps
208
209
Jest matcher for asserting animated props on components.
210
211
```typescript { .api }
212
// Jest matcher interface
213
interface Matchers<R> {
214
toHaveAnimatedProps(props: Record<string, unknown>): R;
215
}
216
```
217
218
**Usage Examples:**
219
220
```typescript
221
const AnimatedTextInput = Animated.createAnimatedComponent(TextInput);
222
223
const MyComponent = () => {
224
const fontSize = useSharedValue(16);
225
const animatedProps = useAnimatedProps(() => ({
226
placeholder: fontSize.value > 18 ? "Large text" : "Small text",
227
maxLength: Math.floor(fontSize.value * 2),
228
}));
229
230
return (
231
<AnimatedTextInput
232
animatedProps={animatedProps}
233
testID="animated-input"
234
/>
235
);
236
};
237
238
it('should have correct animated props', () => {
239
const { getByTestId } = render(<MyComponent />);
240
const component = getByTestId('animated-input');
241
242
expect(component).toHaveAnimatedProps({
243
placeholder: "Small text",
244
maxLength: 32,
245
});
246
});
247
```
248
249
## Types
250
251
### Testing Configuration Types
252
253
```typescript { .api }
254
interface FramerateConfig {
255
/** Frames per second for animation testing (default: 60) */
256
fps?: number;
257
}
258
259
interface ToHaveAnimatedStyleConfig {
260
/** Whether to match all properties exactly (default: false) */
261
shouldMatchAllProps?: boolean;
262
}
263
```
264
265
### Component Types for Testing
266
267
```typescript { .api }
268
type TestComponent = React.Component<
269
AnimatedComponentProps<InitialComponentProps> & {
270
jestAnimatedStyle?: { value: DefaultStyle };
271
jestAnimatedProps?: {
272
value: Partial<AnimatedComponentProps<AnimatedProps>>;
273
};
274
}
275
>;
276
277
type DefaultStyle = Record<string, unknown>;
278
```
279
280
## Best Practices
281
282
### Complete Test Setup
283
284
```typescript
285
// setupTests.js
286
import { setUpTests } from "react-native-reanimated";
287
288
// Set up Reanimated testing utilities
289
setUpTests();
290
291
// Optional: Custom framerate for slower devices or specific testing needs
292
// setUpTests({ fps: 30 });
293
```
294
295
### Animation Testing Pattern
296
297
```typescript
298
describe('Component Animations', () => {
299
beforeEach(() => {
300
jest.useFakeTimers();
301
});
302
303
afterEach(() => {
304
jest.runOnlyPendingTimers();
305
jest.useRealTimers();
306
});
307
308
it('should animate opacity from 0 to 1', () => {
309
const { getByTestId } = render(<FadeInComponent testID="fade" />);
310
const component = getByTestId('fade');
311
312
// Initial state
313
expect(component).toHaveAnimatedStyle({ opacity: 0 });
314
315
// Trigger animation
316
fireEvent.press(getByTestId('trigger-button'));
317
318
// Advance animation
319
jest.advanceTimersByTime(500); // 500ms into animation
320
321
// Check intermediate state
322
expect(component).toHaveAnimatedStyle({ opacity: 0.5 });
323
324
// Complete animation
325
jest.advanceTimersByTime(500);
326
327
// Check final state
328
expect(component).toHaveAnimatedStyle({ opacity: 1 });
329
});
330
});
331
```