VOOZH about

URL: https://deepwiki.com/hypervel/testbench/4.3-handlesdatabases-trait

⇱ HandlesDatabases Trait | hypervel/testbench | DeepWiki


Loading...
Last indexed: 7 February 2026 (93289f)
Menu

HandlesDatabases Trait

Purpose and Scope

The HandlesDatabases trait provides a set of protected hook methods for managing database migrations and seeders within test classes. This trait is included in the TestCase base class and allows test authors to define database setup and teardown logic that executes at specific points in the test lifecycle.

This document covers the trait's structure, method signatures, lifecycle integration, and usage patterns. For information about writing database migrations themselves, see Database Migrations in Tests. For details on the broader test lifecycle where these hooks execute, see Test Lifecycle and Hooks. For the overall context of testing traits, see Testing Traits and Concerns.

Sources: src/Concerns/HandlesDatabases.php1-56


Trait Structure and Methods

The HandlesDatabases trait is defined in the Hypervel\Testbench\Concerns namespace and provides five protected methods that test classes can override to manage database state.

Method Reference

MethodPurposeCalled ByTypical Use Case
defineDatabaseMigrations()Set up database schema before testssetUpDatabaseRequirements()Run migrations, load schema
destroyDatabaseMigrations()Tear down database schema after testsbeforeApplicationDestroyed() callbackRollback migrations, clean up
defineDatabaseSeeders()Populate database with test datasetUpDatabaseRequirements()Seed tables with fixtures
defineDatabaseMigrationsAfterDatabaseRefreshed()Define migrations after refreshTest classesRe-apply migrations post-refresh
setUpDatabaseRequirements()Orchestrate database setup lifecycleTestCase::setUp()Internal framework method

Sources: src/Concerns/HandlesDatabases.php12-56

Method Signatures


Empty hook method called during test setup to define which migrations should run. Test classes override this method to execute migration logic.

src/Concerns/HandlesDatabases.php15-18


Empty hook method called during test teardown to reverse migrations or clean up database state. Registered as a callback via beforeApplicationDestroyed().

src/Concerns/HandlesDatabases.php23-26


Empty hook method called after migrations to seed test data. Executes after defineDatabaseMigrations() completes.

src/Concerns/HandlesDatabases.php31-34


Empty hook method for defining migrations that should run after a database refresh operation. Used with Laravel's RefreshDatabase trait.

src/Concerns/HandlesDatabases.php39-42


Orchestrates the database setup lifecycle. Calls defineDatabaseMigrations(), registers the teardown callback, executes the provided callback, then calls defineDatabaseSeeders().

src/Concerns/HandlesDatabases.php47-55

Sources: src/Concerns/HandlesDatabases.php1-56


Lifecycle Integration

The HandlesDatabases trait integrates into the TestCase lifecycle through the setUpDatabaseRequirements() method, which is called during test setup.

Database Setup Sequence


Database Setup Lifecycle

The setup sequence ensures migrations execute before seeders, and teardown is automatically registered before any custom setup logic runs.

Sources: src/Concerns/HandlesDatabases.php47-55

Integration with TestCase


HandlesDatabases Integration

The trait provides hook methods that test classes override. The setUpDatabaseRequirements() orchestrator calls these hooks in a defined sequence.

Sources: src/Concerns/HandlesDatabases.php1-56


Database Migration Management

The primary purpose of HandlesDatabases is to provide a consistent pattern for setting up and tearing down database schema in tests.

Setup Pattern: defineDatabaseMigrations()

Test classes override defineDatabaseMigrations() to run migrations before each test. This typically involves calling Laravel's migration facade or Hyperf's migration runner.

Common operations in defineDatabaseMigrations():

  • Execute php bin/hyperf.php migrate programmatically
  • Load migrations from specific directories
  • Create tables directly via Schema facade
  • Set up foreign keys and indexes

Example pattern:


Sources: src/Concerns/HandlesDatabases.php15-18

Teardown Pattern: destroyDatabaseMigrations()

Test classes override destroyDatabaseMigrations() to clean up database state after each test. This method is automatically registered as a beforeApplicationDestroyed() callback by setUpDatabaseRequirements().

Common operations in destroyDatabaseMigrations():

  • Execute php bin/hyperf.php migrate:rollback programmatically
  • Drop tables directly via Schema facade
  • Truncate tables for quick cleanup
  • Reset database connections

Example pattern:


The automatic registration ensures cleanup occurs even if the test fails or throws an exception.

Sources: src/Concerns/HandlesDatabases.php23-26 src/Concerns/HandlesDatabases.php50

Migration Execution Flow


Migration Execution Flow

Migrations run during setup, database is used during the test, and cleanup occurs automatically during teardown via the registered callback.

Sources: src/Concerns/HandlesDatabases.php47-55


Seeders and Database Refresh

Seeder Management: defineDatabaseSeeders()

The defineDatabaseSeeders() method executes after migrations complete but before the test begins. This method populates the database with test fixtures.

Common operations in defineDatabaseSeeders():

  • Call seeder classes
  • Create model instances via factories
  • Insert test data directly
  • Set up relationships between models

Example pattern:


Sources: src/Concerns/HandlesDatabases.php31-34 src/Concerns/HandlesDatabases.php54

Post-Refresh Migrations: defineDatabaseMigrationsAfterDatabaseRefreshed()

This hook method is provided for integration with Laravel's RefreshDatabase trait, which wipes the database between tests. After a refresh, this method allows re-applying specific migrations.

Example pattern:


Sources: src/Concerns/HandlesDatabases.php39-42

Seeder Execution Sequence


Seeder Execution Order

Seeders always execute after migrations and callback registration, ensuring the schema exists before data insertion.

Sources: src/Concerns/HandlesDatabases.php47-55


Practical Usage Examples

Example: Workbench User Migration

The workbench environment demonstrates typical HandlesDatabases usage with the create_users_table migration.

Migration structure:

  • Up method: Creates users table with id, name, email, email_verified_at, password, and timestamps columns
  • Down method: Drops the users table if it exists

workbench/database/migrations/2023_08_03_000000_create_users_table.php14-22 - up() method workbench/database/migrations/2023_08_03_000000_create_users_table.php28-31 - down() method

Test class usage pattern:


Sources: workbench/database/migrations/2023_08_03_000000_create_users_table.php1-33

Code Entity Mapping


Code Entity Relationships

The trait methods interact with migrations, schema definitions, and factories to manage database state throughout the test lifecycle.

Sources: src/Concerns/HandlesDatabases.php1-56 workbench/database/migrations/2023_08_03_000000_create_users_table.php1-33


Best Practices

Isolation and Cleanup

  1. Always implement destroyDatabaseMigrations(): Ensure database state doesn't leak between tests
  2. Use transactions when possible: Faster than full migration rollback for simple tests
  3. Avoid persistent state: Each test should start with a clean database
  4. Drop tables explicitly: Don't rely on automatic rollback; be explicit in destroyDatabaseMigrations()

Performance Optimization

  1. Minimize migration count: Only run necessary migrations for the test
  2. Consider in-memory databases: SQLite :memory: for faster tests
  3. Reuse schema when appropriate: Some test suites benefit from shared schema with data cleanup only
  4. Profile migration times: Identify slow migrations and optimize them

Error Handling

  1. Wrap migrations in try-catch: Log useful error messages when migrations fail
  2. Verify schema state: Check that tables exist before running tests
  3. Handle cleanup failures gracefully: Don't let teardown errors mask test failures
  4. Use descriptive migration names: Makes debugging easier when migrations fail

Integration with Other Traits

The HandlesDatabases trait works alongside:

  • HandlesRoutes (see HandlesRoutes Trait): Define routes that interact with database-backed models
  • CreatesApplication (see CreatesApplication Trait): Register providers that configure database connections
  • Database testing utilities from Laravel/Hypervel for assertions and factories

Sources: src/Concerns/HandlesDatabases.php1-56


Method Implementation Details

setUpDatabaseRequirements() Implementation

The setUpDatabaseRequirements() method follows a specific execution order:

  1. Line 49: Calls defineDatabaseMigrations() to set up schema
  2. Line 50: Registers destroyDatabaseMigrations() as a callback via beforeApplicationDestroyed()
  3. Line 52: Executes the provided callback (custom setup logic)
  4. Line 54: Calls defineDatabaseSeeders() to populate data

This order ensures:

  • Schema exists before any data operations
  • Cleanup is registered early, even if subsequent operations fail
  • Custom callbacks execute after schema but before seeders
  • Seeders have a complete schema and callback context

Sources: src/Concerns/HandlesDatabases.php47-55

Empty Hook Pattern

All hook methods in HandlesDatabases are empty by design. This pattern:

  • Allows optional implementation (test classes only override what they need)
  • Provides clear extension points without forcing implementation
  • Maintains backward compatibility when new hooks are added
  • Follows the Template Method design pattern

Example from the trait:


The comment serves as inline documentation for developers discovering these methods.

Sources: src/Concerns/HandlesDatabases.php15-18 src/Concerns/HandlesDatabases.php23-26 src/Concerns/HandlesDatabases.php31-34 src/Concerns/HandlesDatabases.php39-42


Summary

The HandlesDatabases trait provides a standardized interface for database management in Hypervel Testbench:

  • Five hook methods for different stages of database lifecycle
  • Automatic teardown registration via beforeApplicationDestroyed() callback
  • Ordered execution through setUpDatabaseRequirements() orchestrator
  • Optional implementation following the Template Method pattern
  • Integration with TestCase lifecycle for transparent database management

Test classes extend TestCase (which includes this trait) and override the hook methods to define their specific database requirements. The trait handles the orchestration, ensuring consistent setup and teardown order across all tests.

Sources: src/Concerns/HandlesDatabases.php1-56