Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Testdummy Laravel Package

laracasts/testdummy

Generate Eloquent models for tests without factories. Define blueprints and quickly create/build records with sensible defaults, relationships, and overrides—ideal for speeding up Laravel test setup and prototyping with minimal boilerplate.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require --dev laracasts/testdummy
    

    No additional configuration is required if using Laravel 5.5+ (auto-discovery).

  2. First Use Case: Generate a factory for a model (e.g., User):

    php artisan make:factory UserFactory --model=User
    

    Use it in a test:

    use Laracasts\TestDummy\Factory;
    
    $user = Factory::for(User::class)->create();
    
  3. Where to Look First:

    • Factory Files: database/factories/ (auto-generated or manually defined).
    • Test Files: tests/Feature/ or tests/Unit/ for integration examples.
    • Documentation: Focus on the Laracasts TestDummy GitHub repo (if available) or Laravel’s factory documentation for parallels.

Implementation Patterns

Usage Patterns

  1. Basic Model Creation: Replace manual Model::create() calls with TestDummy:

    // Before
    $user = User::create(['name' => 'John', 'email' => 'john@example.com']);
    
    // After
    $user = Factory::for(User::class)->create(['name' => 'John']);
    
  2. Relationships: Define relationships in factories and chain them:

    // UserFactory.php
    public function withPosts()
    {
        return $this->afterCreating(function ($user) {
            Factory::for(Post::class)->count(3)->create(['user_id' => $user->id]);
        });
    }
    
    // Usage
    $user = Factory::for(User::class)->withPosts()->create();
    
  3. Stateful Factories: Use states to define reusable configurations:

    // UserFactory.php
    public function admin()
    {
        return $this->state([
            'role' => 'admin',
            'email' => 'admin@example.com',
        ]);
    }
    
    // Test
    $admin = Factory::for(User::class)->admin()->create();
    
  4. Raw Data Generation: Generate data without persisting to the database:

    $userData = Factory::for(User::class)->raw();
    
  5. Seeding Tests: Use factories in DatabaseSeeder or test-specific seeders:

    public function run()
    {
        Factory::for(User::class)->count(10)->create();
    }
    

Workflows

  1. Test-Driven Development (TDD):

    • Write a failing test, then use TestDummy to generate the required data.
    • Example:
      public function test_user_can_create_post()
      {
          $user = Factory::for(User::class)->create();
          $post = Factory::for(Post::class)->create(['user_id' => $user->id]);
          // Assertions...
      }
      
  2. Integration Testing:

    • Combine with Laravel’s HTTP testing:
      $user = Factory::for(User::class)->create();
      $response = $this->actingAs($user)->post('/posts', ['title' => 'Hello']);
      
  3. Data Migration Testing:

    • Generate test data matching production schemas:
      $oldUser = Factory::for(User::class)->state(['legacy_id' => 123])->create();
      

Integration Tips

  1. Leverage Laravel’s Testing Helpers: Combine with DatabaseTransactions or RefreshDatabase traits:

    use RefreshDatabase;
    
    public function test_something()
    {
        $this->refreshDatabase();
        $user = Factory::for(User::class)->create();
        // Test...
    }
    
  2. Customize Factories Dynamically: Override factory attributes per test:

    $user = Factory::for(User::class)
        ->state(['email' => 'custom@example.com'])
        ->create();
    
  3. Use with Pest PHP: If using Pest, adapt the syntax:

    $user = create(User::class, ['name' => 'John']); // Native Pest
    // Or with TestDummy:
    $user = Factory::for(User::class)->create(['name' => 'John']);
    
  4. Batch Operations: Generate large datasets efficiently:

    $users = Factory::for(User::class)->count(1000)->create();
    

Gotchas and Tips

Pitfalls

  1. Deprecated Laravel Versions:

    • The package may not support Laravel 9+ features (e.g., enums, new factory methods).
    • Fix: Use a compatibility layer or fork the package.
  2. Database Transactions:

    • Forgetting RefreshDatabase or DatabaseTransactions can lead to shared state between tests.
    • Fix: Always use transactions for isolated tests:
      use DatabaseTransactions;
      
      public function test_something()
      {
          $this->beginDatabaseTransaction();
          // Test...
      }
      
  3. Overly Complex Factories:

    • Deeply nested afterCreating or has relationships can become unmaintainable.
    • Fix: Keep factories simple; use separate factory files for complex models.
  4. ID Conflicts:

    • Auto-increment IDs may cause issues in parallel test runs.
    • Fix: Use UUIDs or reset sequences:
      Schema::disableForeignKeyConstraints();
      DB::statement('ALTER TABLE users AUTO_INCREMENT = 1');
      
  5. Missing Auto-Discovery:

    • If using Laravel < 5.5, manually add the service provider:
      Laracasts\TestDummy\TestDummyServiceProvider::class,
      

Debugging

  1. Inspect Raw Data: Use raw() to debug factory output:

    $data = Factory::for(User::class)->raw();
    dd($data);
    
  2. Factory Not Found: Ensure the factory class exists in database/factories/ and follows Laravel’s naming conventions (*Factory.php).

  3. Relationship Errors: Verify afterCreating or has methods are correctly referencing model classes:

    // Wrong (undefined class)
    $this->afterCreating(function ($user) {
        Factory::for(Post::class)->create(['user_id' => $user->id]);
    });
    
    // Right (imported or fully qualified)
    use App\Models\Post;
    
  4. CI Database Issues: SQLite paths may cause failures in CI. Configure .env.testing:

    DB_CONNECTION=sqlite
    DB_DATABASE=:memory:
    

Tips

  1. Reuse Factories Across Tests: Define factories in database/factories/ and reuse them in all test suites.

  2. Combine with Faker: Use Faker’s methods directly in factories:

    public function definition()
    {
        return [
            'name' => $this->faker->name,
            'email' => $this->faker->unique()->safeEmail,
        ];
    }
    
  3. Test Data Consistency: Use state() to enforce consistent test data:

    $user = Factory::for(User::class)
        ->state(['verified' => true])
        ->create();
    
  4. Performance Optimization:

    • Batch inserts for large datasets:
      $users = Factory::for(User::class)->times(1000)->create();
      
    • Use transactions to roll back after tests:
      $this->withoutExceptionHandling();
      $this->afterApplicationCreated(function () {
          DB::rollBack();
      });
      
  5. Extend Native Factories: Hybrid approach with Laravel’s built-in factories:

    $user = User::factory()->create(); // Native
    // Or with TestDummy:
    $user = Factory::for(User::class)->create();
    
  6. Document Factory Usage: Add comments in factories to explain states/relationships:

    /**
     * Creates an admin user with 5 posts.
     */
    public function adminWithPosts()
    {
        return $this->admin()->withPosts();
    }
    
  7. Avoid Hardcoding: Use environment variables or config for dynamic factory data:

    public function definition()
    {
        return [
            'email' => config('testing.default_email'),
        ];
    }
    
  8. Test Factory Behavior: Write tests for factories themselves to ensure data consistency:

    public function test_user_factory_has_email()
    {
        $user = Factory::for(User::class)->create();
        $this->assertEmailIsValid($user->email);
    }
    
  9. Legacy Code Workarounds: For older Laravel versions, manually register the package:

    use Laracasts\TestDummy\TestDummy;
    
    TestDummy::register();
    
  10. Alternative: Use Pest: If adopting Pest PHP, consider its built-in create() helper, which may reduce dependency on testdummy:

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor