symfonycasts/internal-test-helpers
Internal test utilities from SymfonyCasts to streamline PHPUnit and Symfony/Laravel package testing. Provides shared helpers, fixtures, and assertions used across SymfonyCasts projects to reduce boilerplate and keep tests consistent and readable.
Installation Add the package via Composer:
composer require --dev symfonycasts/internal-test-helpers
No additional configuration is required.
First Use Case
Use the TestHelper trait in your test classes to generate realistic test data:
use Symfonycasts\InternalTestHelpers\TestHelper;
class UserTest extends TestCase
{
use TestHelper;
public function test_create_user_with_fake_data()
{
$user = User::factory()->create([
'email' => $this->faker->unique()->safeEmail,
'password' => 'password123',
]);
$this->assertDatabaseHas('users', [
'email' => $user->email,
]);
}
}
Where to Look First
$this->faker for generating fake data (e.g., emails, names, addresses).$this->createModel() and $this->createModels() for quick model creation.$this->assertDatabaseHas() or $this->assertDatabaseMissing() for database checks.Generating Fake Data Leverage Faker for realistic test data:
$user = User::factory()->create([
'name' => $this->faker->name,
'email' => $this->faker->unique()->email,
]);
Model Creation
Use createModel() for one-off model creation or createModels() for bulk creation:
$post = $this->createModel(Post::class, ['title' => 'Test Post']);
$posts = $this->createModels(Post::class, 5); // Creates 5 posts
Database Assertions Verify database state without querying:
$this->assertDatabaseHas('posts', ['title' => 'Test Post']);
$this->assertDatabaseMissing('posts', ['title' => 'Deleted Post']);
Testing API Endpoints Combine with Laravel's HTTP tests:
$response = $this->postJson('/api/users', [
'email' => $this->faker->unique()->email,
'password' => 'password123',
]);
$this->assertDatabaseHas('users', ['email' => $response['email']]);
Seeding Relationships Create nested relationships easily:
$user = $this->createModel(User::class);
$posts = $this->createModels(Post::class, 3, ['user_id' => $user->id]);
setUp() to seed test data once per test class.refreshDatabase()) handle rollbacks, but manually delete test data if needed:
public function tearDown(): void
{
User::where('email', 'like', '%@test.com')->delete();
parent::tearDown();
}
$user = User::factory()->create([
'role' => $this->faker->randomElement(['admin', 'editor', 'user']),
]);
$this->faker->addProvider(new CustomFakerProvider($this->faker));
Faker State Persistence
$this->faker->seed(1234); // Reset seed for reproducibility
$this->faker->unique() in loops without resetting seeds.Database Assertions vs. Queries
assertDatabaseHas() is slower than direct queries. Use it for critical checks only.Model Creation Quirks
createModel() uses create(), not factory(). Ensure your models support both.fill() + save() for safety:
$post = new Post();
$post->fill(['title' => $this->faker->sentence])->save();
Testing Observers/Events
createModel(). Disable them in tests if needed:
User::observe();
User::observe(NoOpObserver::class); // Replace with a no-op observer
dd($this->faker->format('The email is %email%'));
$this->assertDatabaseCount('posts', 1);
$this->withoutExceptionHandling(); // Temporarily disable exceptions
setUp():
public function setUp(): void
{
parent::setUp();
$this->faker->addProvider(new AppFakerProvider($this->faker));
}
Custom Helpers Extend the trait or create your own:
trait CustomTestHelper
{
protected function createAdminUser(): User
{
return $this->createModel(User::class, [
'email' => $this->faker->unique()->email,
'role' => 'admin',
]);
}
}
Faker Providers Add domain-specific providers:
$this->faker->addProvider(new class($this->faker) extends FakerProvider {
public function paymentMethod(): string
{
return $this->faker->randomElement(['credit_card', 'paypal', 'bank_transfer']);
}
});
Assertion Macros Extend Laravel’s assertions:
use Illuminate\Testing\Assertions;
Assertions::macro('seeUserInDatabase', function ($email) {
$this->assertDatabaseHas('users', ['email' => $email]);
});
Test Data Factories Combine with Laravel’s factories for complex setups:
$user = User::factory()->create();
Post::factory()->count(5)->create(['user_id' => $user->id]);
How can I help you explore Laravel packages today?