Flutter Fixtures SQLite

pub package

SQLite/sqflite implementation for the Flutter Fixtures library. Mock database queries with fixture files for testing and development.

🎯 Purpose

This package provides a fixture-backed DatabaseAdapter for SQLite, allowing you to:

  • Mock database queries during development and testing
  • Test different data scenarios without modifying the database
  • Develop UI features before the database schema is finalized
  • Create reproducible test scenarios

📦 What's Included

FixtureDatabase

A drop-in replacement for sqflite's Database that returns fixture data. Provides the same familiar API (query, insert, update, delete) so you can swap between fixture and real databases easily.

SqfliteDataQuery

The file-backed SqfliteFixtureSource: loads fixture files from your app's assets and returns them as fixture collections. Implement SqfliteFixtureSource yourself to provide fixtures from anywhere else.

SqfliteQuery

A model class representing database queries for fixture matching.

🚀 Installation

Add the package to your pubspec.yaml:

dependencies:
  flutter_fixtures_sqflite: ^0.3.0
  sqflite: ^2.4.1

📁 Fixture File Structure

Create fixture files in assets/fixtures/database/ directory:

assets/
  fixtures/
    database/
      query_users.json
      query_products.json
      insert_orders.json

Fixture File Format

{
  "description": "User table query fixtures",
  "values": [
    {
      "identifier": "success",
      "description": "Returns list of users",
      "default": true,
      "data": [
        {"id": 1, "name": "John", "email": "john@example.com"},
        {"id": 2, "name": "Jane", "email": "jane@example.com"}
      ]
    },
    {
      "identifier": "empty",
      "description": "Returns empty result",
      "data": []
    },
    {
      "identifier": "single",
      "description": "Returns single user",
      "data": [
        {"id": 1, "name": "John", "email": "john@example.com"}
      ]
    }
  ]
}

💡 Usage

Use FixtureDatabase as a drop-in replacement for sqflite's Database:

import 'package:flutter_fixtures_sqflite/flutter_fixtures_sqflite.dart';
import 'package:flutter_fixtures_core/flutter_fixtures_core.dart';

// Create a fixture database (same API as sqflite's Database)
final db = FixtureDatabase(
  dataQuery: SqfliteDataQuery(),
  dataSelector: DataSelectorType.defaultValue,
);

// Query just like a real sqflite database!
final users = await db.query('users');
final products = await db.query('products', where: 'category = ?');

// Insert, update, delete also work
final id = await db.insert('users', {'name': 'John', 'email': 'john@example.com'});
await db.update('users', {'name': 'Jane'}, where: 'id = ?');
await db.delete('users', where: 'id = ?');

With Interactive Fixture Selection

FixturesDialogView comes from the flutter_fixtures_ui package — add it to your dev dependencies alongside this one.

final db = FixtureDatabase(
  dataQuery: SqfliteDataQuery(),
  dataSelector: DataSelectorType.pick,
  dataSelectorView: FixturesDialogView.of(context),
  delay: DataSelectorDelay.fast,
);

// When querying, a dialog will let you pick which fixture to return
final users = await db.query('users');

Low-Level API

For more control, use SqfliteDataQuery directly:

final dataQuery = SqfliteDataQuery();

// Create a query
final query = SqfliteQuery.table(
  table: 'users',
  operation: SqfliteOperation.query,
);

// Find and parse fixtures
final fixtureData = await dataQuery.find(query);
if (fixtureData != null) {
  final collection = await dataQuery.parse(fixtureData);
  final selected = await dataQuery.select(
    collection!,
    null,
    DataSelectorType.defaultValue,
  );
  final result = await dataQuery.data(selected!);
  print(result);
}

File Naming Convention

Files should be named based on the query operation and table:

Query Type File Name
SELECT on users query_users.json
INSERT on users insert_users.json
UPDATE on users update_users.json
DELETE on users delete_users.json
SELECT with WHERE query_users_id_1.json
Raw SQL query rawQuery_{normalized_sql}.json

📄 License

MIT License - see LICENSE for details.

Record & replay

This package also ships RecorderDatabaseAdapter, a record & replay decorator over any DatabaseAdapter: capture real query results and mutations while exercising the app, then replay them later in recorded order — without touching the database. The engine and UI tools live in flutter_fixtures_recorder; this adapter only talks to the thin TrafficRecorder seam in core.

final db = RecorderDatabaseAdapter(
  inner: RealDatabaseAdapter(await openDatabase("app.db")),
  recorder: recorder,
);

See the recorder package README for sessions, storage, and ordering semantics.