Skip to main content

Schema Validation

server_testing provides powerful schema validation capabilities through AssertableJson.

Basic Schema Validation

response.assertJson((json) {
json.matchesSchema({
// Basic types
'id': int,
'name': String,
'active': bool,
'score': double,

// Nested objects
'profile': {
'email': String,
'age': int,
'preferences': Map<String, dynamic>
},

// Arrays
'tags': List<String>,
'scores': List<int>,
'records': List<Map<String, dynamic>>
});
});

Array Structure Validation

response.assertJson((json) {
// Validate array item structure
json.assertStructure({
'users': {
'*': [ // Wildcard matches all array items
'id',
'name',
'email'
]
},

// Nested arrays
'departments': {
'*': { // Each department
'name': String,
'employees': {
'*': [ // Each employee
'id',
'role'
]
}
}
}
});
});

Optional Fields

response.assertJson((json) {
json.matchesSchema({
// Required fields
'id': int,
'name': String,

// Optional fields (nullable)
'description?': String,
'metadata?': Map<String, dynamic>,

// Nested optional fields
'profile': {
'email': String,
'phone?': String,
'address?': {
'street': String,
'city': String
}
}
});
});

Type Validation

response.assertJson((json) {
json
// Direct type checks
.whereType<int>('id')
.whereType<String>('name')
.whereType<bool>('active')
.whereType<List>('items')
.whereType<Map>('metadata')

// Nested type checks
.scope('user', (user) {
user
.whereType<String>('email')
.whereType<int>('age')
.scope('settings', (settings) {
settings.whereType<bool>('notifications');
});
});
});

Custom Validation

response.assertJson((json) {
json
// Custom validation function
.where('email', (value) {
return RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$')
.hasMatch(value as String);
})

// Custom type validation
.where('date', (value) {
return DateTime.tryParse(value as String) != null;
})

// Complex validation
.where('permissions', (value) {
final perms = value as List;
return perms.every((p) =>
p is String && ['read', 'write', 'admin'].contains(p));
});
});

Combining Validations

response.assertJson((json) {
json
// Schema validation
.matchesSchema({
'user': {
'id': int,
'name': String,
'email': String
}
})

// Additional type checks
.whereType<int>('user.id')

// Value validation
.where('user.id', (id) => id > 0)

// Nested validation
.scope('user', (user) {
user
.has('id')
.has('name')
.has('email')
.whereType<String>('email')
.where('email', (email) =>
email.toString().contains('@'));
});
});