12 KiB
12 KiB
API Mock Data Guide
If you don't have a backend API ready yet, you can use mock data to test the app. This guide shows you how to create and use mock data.
Creating Mock Data
Option 1: Modify RouteApiService
Edit lib/services/api/route_api_service.dart and replace the API calls with mock data:
import 'package:uuid/uuid.dart';
Future<List<RouteModel>> getDriverRoutes(String driverId) async {
// Simulate network delay
await Future.delayed(const Duration(seconds: 1));
// Return mock data
return [
RouteModel(
id: 'RT001',
driverId: driverId,
driverName: 'John Doe',
date: DateTime.now(),
status: RouteStatus.notStarted,
totalDistance: 45.5,
estimatedDuration: 120,
vehicleId: 'VH123',
stops: [
StopModel(
id: 'ST001',
customerId: 'C001',
customerName: 'Acme Corporation',
customerPhone: '+1234567890',
location: LocationModel(
latitude: 37.7749,
longitude: -122.4194,
address: '123 Market St, San Francisco, CA 94103',
),
type: StopType.pickup,
status: StopStatus.pending,
scheduledTime: DateTime.now().add(const Duration(hours: 1)),
items: ['Package A', 'Package B', 'Package C'],
orderNumber: 1,
),
StopModel(
id: 'ST002',
customerId: 'C002',
customerName: 'Tech Solutions Inc',
customerPhone: '+1234567891',
location: LocationModel(
latitude: 37.7849,
longitude: -122.4094,
address: '456 Mission St, San Francisco, CA 94105',
),
type: StopType.dropoff,
status: StopStatus.pending,
scheduledTime: DateTime.now().add(const Duration(hours: 2)),
items: ['Package A', 'Package B'],
orderNumber: 2,
),
StopModel(
id: 'ST003',
customerId: 'C003',
customerName: 'Global Supplies Ltd',
customerPhone: '+1234567892',
location: LocationModel(
latitude: 37.7949,
longitude: -122.3994,
address: '789 Howard St, San Francisco, CA 94107',
),
type: StopType.dropoff,
status: StopStatus.pending,
scheduledTime: DateTime.now().add(const Duration(hours: 3)),
items: ['Package C'],
orderNumber: 3,
),
],
),
RouteModel(
id: 'RT002',
driverId: driverId,
driverName: 'John Doe',
date: DateTime.now().add(const Duration(days: 1)),
status: RouteStatus.notStarted,
totalDistance: 32.8,
estimatedDuration: 90,
vehicleId: 'VH123',
stops: [
StopModel(
id: 'ST004',
customerId: 'C004',
customerName: 'Downtown Retail',
customerPhone: '+1234567893',
location: LocationModel(
latitude: 37.7649,
longitude: -122.4294,
address: '321 Broadway, San Francisco, CA 94133',
),
type: StopType.pickup,
status: StopStatus.pending,
scheduledTime: DateTime.now().add(const Duration(days: 1, hours: 1)),
items: ['Box 1', 'Box 2'],
orderNumber: 1,
),
],
),
];
}
Future<RouteModel?> getRouteById(String routeId) async {
await Future.delayed(const Duration(seconds: 1));
final routes = await getDriverRoutes('driver_1');
return routes.firstWhere(
(route) => route.id == routeId,
orElse: () => routes.first,
);
}
Future<bool> updateRouteStatus(String routeId, RouteStatus status) async {
await Future.delayed(const Duration(milliseconds: 500));
// Simulate successful update
return true;
}
Future<bool> updateStopStatus(
String routeId,
String stopId,
StopStatus status, {
String? signature,
String? photo,
String? notes,
}) async {
await Future.delayed(const Duration(milliseconds: 500));
// Simulate successful update
return true;
}
Future<bool> reportIssue(String routeId, String stopId, String issue) async {
await Future.delayed(const Duration(milliseconds: 500));
// Simulate successful report
return true;
}
Option 2: Create a Mock Provider
Create a separate mock service that you can easily swap:
- Create
lib/services/api/mock_route_api_service.dart:
import 'route_api_service.dart';
import '../../features/routes/data/models/route_model.dart';
import '../../features/routes/data/models/stop_model.dart';
import '../../features/routes/data/models/location_model.dart';
class MockRouteApiService extends RouteApiService {
final List<RouteModel> _mockRoutes = [
// Add your mock routes here
];
@override
Future<List<RouteModel>> getDriverRoutes(String driverId) async {
await Future.delayed(const Duration(seconds: 1));
return _mockRoutes;
}
@override
Future<RouteModel?> getRouteById(String routeId) async {
await Future.delayed(const Duration(seconds: 1));
return _mockRoutes.firstWhere(
(route) => route.id == routeId,
orElse: () => _mockRoutes.first,
);
}
@override
Future<bool> updateRouteStatus(String routeId, RouteStatus status) async {
await Future.delayed(const Duration(milliseconds: 500));
return true;
}
@override
Future<bool> updateStopStatus(
String routeId,
String stopId,
StopStatus status, {
String? signature,
String? photo,
String? notes,
}) async {
await Future.delayed(const Duration(milliseconds: 500));
return true;
}
@override
Future<bool> reportIssue(String routeId, String stopId, String issue) async {
await Future.delayed(const Duration(milliseconds: 500));
return true;
}
}
- Use it in
main.dart:
void main() {
// Use mock service for development
// RouteApiService().initialize(); // Production
// In development, the provider will use mock data automatically
runApp(const FleetDriverApp());
}
Mock Data Generator
Here's a utility to generate random mock data for testing:
import 'dart:math';
import 'package:uuid/uuid.dart';
class MockDataGenerator {
static final _random = Random();
static final _uuid = Uuid();
static final List<String> _customerNames = [
'Acme Corporation',
'Tech Solutions Inc',
'Global Supplies Ltd',
'Downtown Retail',
'Bay Area Logistics',
'Pacific Trading Co',
'Metro Wholesale',
'Summit Distribution',
];
static final List<String> _addresses = [
'123 Market St, San Francisco, CA',
'456 Mission St, San Francisco, CA',
'789 Howard St, San Francisco, CA',
'321 Broadway, San Francisco, CA',
'654 Valencia St, San Francisco, CA',
'987 Geary Blvd, San Francisco, CA',
];
static final List<String> _items = [
'Package A',
'Package B',
'Package C',
'Box 1',
'Box 2',
'Crate 1',
'Pallet A',
'Container X',
];
static RouteModel generateRoute({
required String driverId,
int stopCount = 3,
}) {
final stops = List.generate(
stopCount,
(index) => generateStop(orderNumber: index + 1),
);
return RouteModel(
id: 'RT${_random.nextInt(9999).toString().padLeft(4, '0')}',
driverId: driverId,
driverName: 'Driver ${_random.nextInt(100)}',
date: DateTime.now().add(Duration(days: _random.nextInt(7))),
status: RouteStatus.values[_random.nextInt(RouteStatus.values.length)],
stops: stops,
totalDistance: 20.0 + _random.nextDouble() * 80,
estimatedDuration: 60 + _random.nextInt(180),
vehicleId: 'VH${_random.nextInt(999)}',
);
}
static StopModel generateStop({required int orderNumber}) {
return StopModel(
id: _uuid.v4(),
customerId: 'C${_random.nextInt(9999)}',
customerName: _customerNames[_random.nextInt(_customerNames.length)],
customerPhone: '+1${_random.nextInt(999999999).toString().padLeft(9, '0')}',
location: LocationModel(
latitude: 37.7749 + (_random.nextDouble() - 0.5) * 0.1,
longitude: -122.4194 + (_random.nextDouble() - 0.5) * 0.1,
address: _addresses[_random.nextInt(_addresses.length)],
),
type: _random.nextBool() ? StopType.pickup : StopType.dropoff,
status: StopStatus.values[_random.nextInt(StopStatus.values.length)],
scheduledTime: DateTime.now().add(Duration(hours: orderNumber)),
items: List.generate(
1 + _random.nextInt(4),
(_) => _items[_random.nextInt(_items.length)],
),
orderNumber: orderNumber,
);
}
static List<RouteModel> generateRoutes({
required String driverId,
int count = 5,
}) {
return List.generate(
count,
(_) => generateRoute(driverId: driverId),
);
}
}
Usage:
// In route_api_service.dart
Future<List<RouteModel>> getDriverRoutes(String driverId) async {
await Future.delayed(const Duration(seconds: 1));
return MockDataGenerator.generateRoutes(driverId: driverId, count: 5);
}
Testing with Mock Data
Local Testing
- Use mock data during development
- Test all UI states (loading, error, empty, success)
- Test edge cases (no routes, single route, many routes)
State Testing
Test different route and stop statuses:
- Routes: notStarted, inProgress, completed, cancelled
- Stops: pending, inProgress, completed, failed
Example Test Scenarios
// Test empty state
Future<List<RouteModel>> getDriverRoutes(String driverId) async {
return [];
}
// Test error state
Future<List<RouteModel>> getDriverRoutes(String driverId) async {
throw Exception('Network error');
}
// Test single route
Future<List<RouteModel>> getDriverRoutes(String driverId) async {
return [MockDataGenerator.generateRoute(driverId: driverId)];
}
// Test many routes
Future<List<RouteModel>> getDriverRoutes(String driverId) async {
return MockDataGenerator.generateRoutes(driverId: driverId, count: 20);
}
Switching to Real API
When your backend is ready:
- Update API base URL in
lib/core/constants/app_constants.dart:
static const String baseApiUrl = 'https://your-api-url.com/api';
-
Remove mock data from
route_api_service.dart -
Ensure your API returns data in the expected format (matching the models)
-
Test with real API:
flutter run --dart-define=API_URL=https://your-api-url.com/api
API Response Format
Your backend should return JSON in this format:
Get Routes Response
[
{
"id": "RT001",
"driverId": "driver_1",
"driverName": "John Doe",
"date": "2025-10-27T10:00:00Z",
"status": "notStarted",
"totalDistance": 45.5,
"estimatedDuration": 120,
"vehicleId": "VH123",
"stops": [
{
"id": "ST001",
"customerId": "C001",
"customerName": "Acme Corporation",
"customerPhone": "+1234567890",
"location": {
"latitude": 37.7749,
"longitude": -122.4194,
"address": "123 Market St, San Francisco, CA"
},
"type": "pickup",
"status": "pending",
"scheduledTime": "2025-10-27T11:00:00Z",
"items": ["Package A", "Package B"],
"orderNumber": 1
}
]
}
]
Tips for Mock Data
- Use realistic data: Coordinates, addresses, names
- Test edge cases: Empty lists, null values, long strings
- Simulate delays: Add realistic network delays
- Test errors: Simulate network failures and API errors
- Use different statuses: Test all possible states
- Generate varied data: Different route lengths, stop counts
- Include optional fields: Test with and without optional data