0
# JSON Fixtures
1
2
JSON fixture management system for loading test data from external JSON files with automatic caching and data isolation. Perfect for testing components that process complex data structures without embedding large data objects in test files.
3
4
## Capabilities
5
6
### Global JSON Fixture Functions
7
8
#### loadJSONFixtures
9
10
Loads JSON fixture(s) from files and returns data object.
11
12
```javascript { .api }
13
/**
14
* Loads JSON fixture(s) from one or more files and returns data object
15
* Data is keyed by filename for easy access
16
* @param fixtureUrls - One or more JSON fixture file URLs/paths
17
* @returns Object with fixture data keyed by filename
18
*/
19
function loadJSONFixtures(...fixtureUrls);
20
```
21
22
**Usage Examples:**
23
```javascript
24
// Load single JSON fixture
25
var fixtures = loadJSONFixtures('users.json');
26
var users = fixtures['users.json'];
27
28
// Load multiple JSON fixtures
29
var data = loadJSONFixtures('users.json', 'products.json', 'orders.json');
30
var users = data['users.json'];
31
var products = data['products.json'];
32
var orders = data['orders.json'];
33
34
// Test with loaded data
35
expect(users).toHaveLength(3);
36
expect(products[0]).toHaveProperty('name');
37
```
38
39
#### getJSONFixture
40
41
Retrieves specific JSON fixture data by filename.
42
43
```javascript { .api }
44
/**
45
* Retrieves specific JSON fixture data by filename
46
* Must be called after loadJSONFixtures() for the same file
47
* @param fixtureUrl - JSON fixture file URL/path
48
* @returns Parsed JSON data for the specified fixture
49
*/
50
function getJSONFixture(fixtureUrl);
51
```
52
53
**Usage Example:**
54
```javascript
55
// Load fixtures first
56
loadJSONFixtures('users.json', 'config.json');
57
58
// Get specific fixture data
59
var users = getJSONFixture('users.json');
60
var config = getJSONFixture('config.json');
61
62
// Use in tests
63
expect(config.apiUrl).toBe('https://api.example.com');
64
expect(users[0].name).toBe('Alice');
65
```
66
67
### JSON Fixture Management Class
68
69
Access JSON fixture management through `jasmine.getJSONFixtures()`:
70
71
```javascript { .api }
72
/**
73
* JSON Fixture management singleton
74
*/
75
interface JSONFixtures {
76
/** File path for JSON fixture files (default: 'spec/javascripts/fixtures/json') */
77
fixturesPath: string;
78
79
/** Internal cache object for loaded JSON fixtures */
80
fixturesCache_: object;
81
82
/** Load JSON fixtures from files and return data object */
83
load(...fixtureUrls): object;
84
85
/** Load JSON fixtures into cache and return cache object (same as load) */
86
read(...fixtureUrls): object;
87
88
/** Clear JSON fixture cache */
89
clearCache(): void;
90
}
91
92
// Access the singleton
93
var jsonFixtures = jasmine.getJSONFixtures();
94
```
95
96
**Configuration and Usage:**
97
```javascript
98
// Customize JSON fixture path
99
jasmine.getJSONFixtures().fixturesPath = 'test/fixtures/data';
100
101
// Use JSON fixture methods directly
102
var data = jasmine.getJSONFixtures().load('test-data.json');
103
jasmine.getJSONFixtures().clearCache();
104
```
105
106
### JSON Loading Behavior
107
108
#### File Loading
109
- JSON files loaded via synchronous AJAX requests
110
- Files loaded relative to `fixturesPath` configuration
111
- JSON content parsed automatically
112
- Multiple files stored separately by filename key
113
114
#### Data Access Patterns
115
- Data returned as object with filename keys
116
- Each fixture file becomes a property in returned object
117
- Use bracket notation to access: `data['filename.json']`
118
- Use `getJSONFixture()` for direct single-file access
119
120
#### Caching and Data Isolation
121
- All loaded JSON fixtures automatically cached by filename
122
- **Important**: `load()` refetches data each time for isolation
123
- Modifications to returned data don't affect cache
124
- Cache persists across test runs unless manually cleared
125
126
### Data Structure Examples
127
128
#### Example JSON Fixture Files
129
130
**users.json:**
131
```json
132
[
133
{
134
"id": 1,
135
"name": "Alice Johnson",
136
"email": "alice@example.com",
137
"active": true,
138
"roles": ["user", "admin"]
139
},
140
{
141
"id": 2,
142
"name": "Bob Smith",
143
"email": "bob@example.com",
144
"active": false,
145
"roles": ["user"]
146
}
147
]
148
```
149
150
**config.json:**
151
```json
152
{
153
"apiUrl": "https://api.example.com",
154
"timeout": 5000,
155
"features": {
156
"authentication": true,
157
"notifications": false
158
},
159
"supportedLanguages": ["en", "es", "fr"]
160
}
161
```
162
163
#### Using JSON Fixtures in Tests
164
165
**Basic Data Loading:**
166
```javascript
167
describe('User management', function() {
168
var users;
169
170
beforeEach(function() {
171
var fixtures = loadJSONFixtures('users.json');
172
users = fixtures['users.json'];
173
});
174
175
it('should process user data', function() {
176
expect(users).toHaveLength(2);
177
expect(users[0].name).toBe('Alice Johnson');
178
expect(users[0].roles).toContain('admin');
179
});
180
181
it('should filter active users', function() {
182
var activeUsers = users.filter(user => user.active);
183
expect(activeUsers).toHaveLength(1);
184
expect(activeUsers[0].name).toBe('Alice Johnson');
185
});
186
});
187
```
188
189
**Configuration Testing:**
190
```javascript
191
describe('Application configuration', function() {
192
var config;
193
194
beforeEach(function() {
195
config = getJSONFixture('config.json');
196
});
197
198
it('should have correct API configuration', function() {
199
expect(config.apiUrl).toBe('https://api.example.com');
200
expect(config.timeout).toBe(5000);
201
});
202
203
it('should have feature flags', function() {
204
expect(config.features.authentication).toBe(true);
205
expect(config.features.notifications).toBe(false);
206
});
207
});
208
```
209
210
### Data Isolation and Modification
211
212
#### Fresh Data Each Load
213
```javascript
214
it('should provide fresh data each time', function() {
215
// Load data first time
216
var data1 = loadJSONFixtures('users.json');
217
var users1 = data1['users.json'];
218
219
// Modify the data
220
users1[0].name = 'Modified Name';
221
222
// Load data second time - should be fresh
223
var data2 = loadJSONFixtures('users.json');
224
var users2 = data2['users.json'];
225
226
expect(users2[0].name).toBe('Alice Johnson'); // Original name, not modified
227
});
228
```
229
230
#### Safe Data Manipulation
231
```javascript
232
describe('Data manipulation tests', function() {
233
var testUsers;
234
235
beforeEach(function() {
236
// Get fresh copy for each test
237
testUsers = getJSONFixture('users.json');
238
});
239
240
it('should modify user data safely', function() {
241
// Safe to modify testUsers - won't affect other tests
242
testUsers[0].active = false;
243
testUsers.push({id: 3, name: 'Charlie', email: 'charlie@example.com'});
244
245
expect(testUsers).toHaveLength(3);
246
expect(testUsers[0].active).toBe(false);
247
});
248
249
it('should have original data in new test', function() {
250
// testUsers is fresh copy, not affected by previous test
251
expect(testUsers).toHaveLength(2);
252
expect(testUsers[0].active).toBe(true);
253
});
254
});
255
```
256
257
### Advanced Usage Patterns
258
259
#### Complex Data Processing
260
```javascript
261
describe('Data processing pipeline', function() {
262
var rawData, processedData;
263
264
beforeEach(function() {
265
var fixtures = loadJSONFixtures('raw-data.json', 'lookup-tables.json');
266
rawData = fixtures['raw-data.json'];
267
var lookups = fixtures['lookup-tables.json'];
268
269
// Process data using multiple fixtures
270
processedData = rawData.map(item => ({
271
...item,
272
categoryName: lookups.categories[item.categoryId],
273
statusText: lookups.statuses[item.status]
274
}));
275
});
276
277
it('should enrich data with lookup values', function() {
278
expect(processedData[0]).toHaveProperty('categoryName');
279
expect(processedData[0]).toHaveProperty('statusText');
280
});
281
});
282
```
283
284
#### API Response Mocking
285
```javascript
286
describe('API integration', function() {
287
it('should handle user list response', function() {
288
var mockResponse = getJSONFixture('api-responses/users-list.json');
289
290
// Simulate API response processing
291
var users = mockResponse.data;
292
var pagination = mockResponse.pagination;
293
294
expect(users).toHaveLength(mockResponse.pagination.perPage);
295
expect(pagination.total).toBeGreaterThan(users.length);
296
});
297
298
it('should handle error responses', function() {
299
var errorResponse = getJSONFixture('api-responses/error-401.json');
300
301
expect(errorResponse.error.code).toBe(401);
302
expect(errorResponse.error.message).toContain('Unauthorized');
303
});
304
});
305
```
306
307
### Error Handling
308
309
The JSON fixture system throws errors for:
310
311
```javascript { .api }
312
/**
313
* Specific error messages thrown by JSON fixture system:
314
* - "JSONFixture could not be loaded: [url] (status: [status], message: [message])"
315
*
316
* These errors occur when:
317
* - JSON fixture file doesn't exist at specified path
318
* - Network/file access issues during AJAX loading
319
* - JSON parsing errors for malformed JSON files
320
* - Invalid file paths or permission issues
321
* - JSON files contain syntax errors or invalid JSON
322
*/
323
```
324
325
**Error Handling Example:**
326
```javascript
327
try {
328
var data = loadJSONFixtures('missing-file.json');
329
} catch (error) {
330
expect(error.message).toContain('JSONFixture could not be loaded');
331
}
332
```
333
334
### Configuration
335
336
#### Default Configuration
337
```javascript
338
{
339
fixturesPath: 'spec/javascripts/fixtures/json' // Default JSON fixture directory (subdirectory of fixtures)
340
}
341
```
342
343
#### Custom Configuration
344
```javascript
345
// Set custom JSON fixture path
346
jasmine.getJSONFixtures().fixturesPath = 'test/data/json';
347
348
// Verify configuration
349
expect(jasmine.getJSONFixtures().fixturesPath).toBe('test/data/json');
350
```
351
352
### Best Practices
353
354
#### Organize JSON Fixtures by Purpose
355
```
356
spec/javascripts/fixtures/json/
357
├── users/
358
│ ├── admin-users.json
359
│ ├── regular-users.json
360
│ └── inactive-users.json
361
├── api-responses/
362
│ ├── success-responses.json
363
│ └── error-responses.json
364
└── config/
365
├── development.json
366
└── production.json
367
```
368
369
#### Use Descriptive Fixture Names
370
```javascript
371
// Good - descriptive names
372
loadJSONFixtures('users/admin-users.json', 'config/test-settings.json');
373
374
// Less clear
375
loadJSONFixtures('data1.json', 'settings.json');
376
```
377
378
#### Combine with Other Fixtures
379
```javascript
380
describe('Complete component test', function() {
381
beforeEach(function() {
382
// Load HTML structure
383
loadFixtures('user-table.html');
384
385
// Load CSS styles
386
loadStyleFixtures('table-styles.css');
387
388
// Load test data
389
var userData = getJSONFixture('users/sample-users.json');
390
391
// Populate component with test data
392
populateUserTable(userData);
393
});
394
395
it('should render users correctly', function() {
396
expect($('.user-row')).toHaveLength(3);
397
expect($('.user-name').first()).toHaveText('Alice Johnson');
398
});
399
});
400
```