Тестирование
Weaver ORM provides a dedicated testing toolkit that makes it straightforward to write fast, reliable tests for code that interacts with the database.
WeaverTestCase
Extend Weaver\ORM\Testing\WeaverTestCase as the base class for any test that needs the ORM. It bootstraps a minimal Symfony kernel, configures the database connection, and provides helper methods for working with entities.
<?php
namespace Tests\Integration;
use Weaver\ORM\Testing\WeaverTestCase;
use App\Entity\User;
class UserRepositoryTest extends WeaverTestCase
{
public function test_find_active_users(): void
{
// Create test data using the factory
$alice = $this->factory(User::class)->create(['status' => 'active']);
$bob = $this->factory(User::class)->create(['status' => 'inactive']);
$result = $this->getRepository(User::class)->findBy(['status' => 'active']);
$this->assertCount(1, $result);
$this->assertSame($alice->getId(), $result->first()->getId());
}
}
EntityFactory — creating test fixtures
Weaver\ORM\Testing\EntityFactory generates entities with sensible defaults and persists them to the database. Define a factory for each entity by extending EntityFactory:
<?php
namespace Tests\Factory;
use App\Entity\User;
use Weaver\ORM\Testing\EntityFactory;
/**
* @extends EntityFactory<User>
*/
class UserFactory extends EntityFactory
{
protected function entity(): string
{
return User::class;
}
protected function defaults(): array
{
return [
'name' => $this->faker->name(),
'email' => $this->faker->unique()->safeEmail(),
'role' => 'user',
'status' => 'active',
'password' => password_hash('secret', PASSWORD_BCRYPT),
];
}
}
Using the factory
<?php
// Create and persist one entity with default values
$user = UserFactory::new()->create();
// Override specific fields
$admin = UserFactory::new()->create([
'role' => 'admin',
'email' => 'admin@example.com',
]);
// Create multiple entities at once
$users = UserFactory::new()->createMany(5);
// Create without persisting (useful for unit tests)
$user = UserFactory::new()->make(['name' => 'Draft User']);
Factory states
Define named states to group related overrides:
<?php
class UserFactory extends EntityFactory
{
// ...
public function admin(): static
{
return $this->state(['role' => 'admin', 'is_staff' => true]);
}
public function inactive(): static
{
return $this->state(['status' => 'inactive']);
}
public function unverified(): static
{
return $this->state(['email_verified_at' => null]);
}
}
// Usage:
$admin = UserFactory::new()->admin()->create();
$inactiveAdmin = UserFactory::new()->admin()->inactive()->create();
$unverifiedUsers = UserFactory::new()->unverified()->createMany(3);
DatabaseTransactions trait
Use the DatabaseTransactions trait to wrap each test in a transaction that is rolled back after the test completes. This is the fastest way to keep tests isolated without truncating tables.
<?php
namespace Tests\Integration;
use Weaver\ORM\Testing\WeaverTestCase;
use Weaver\ORM\Testing\DatabaseTransactions;
use Tests\Factory\OrderFactory;
class OrderRepositoryTest extends WeaverTestCase
{
use DatabaseTransactions; // transaction opened before each test, rolled back after
public function test_find_pending_orders(): void
{
OrderFactory::new()->create(['status' => 'pending']);
OrderFactory::new()->create(['status' => 'shipped']);
$pending = $this->getRepository(\App\Entity\Order::class)
->findBy(['status' => 'pending']);
$this->assertCount(1, $pending);
}
// Database is fully clean after this test — no cleanup code needed
}
The trait hooks into setUp and tearDown to begin and roll back the transaction automatically. All changes made during the test — including any push() calls — are discarded at the end.