Weave 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

Doctrine Static Laravel Package

bentools/doctrine-static

Lightweight in-memory Doctrine mock for unit tests. Create ObjectManagers in a ManagerRegistry, persist/remove and flush to a temporary store, and use repository methods like find, findBy, findOneBy, and findAll. Not for real persistence.

View on GitHub
Deep Wiki
Context7
## Technical Evaluation

### Architecture Fit
- **Test-Doubling Layer**: Perfectly aligns with **unit/integration testing** for Doctrine ORM, replacing database dependencies in CI/CD pipelines. Fits the **test pyramid** by enabling isolated business logic validation.
- **Laravel Context**: While Laravel primarily uses Eloquent, this package is valuable for:
  - **Legacy Doctrine systems** integrated with Laravel.
  - **Hybrid architectures** (e.g., API layers using Doctrine for complex queries).
  - **Service-layer testing** where Doctrine repositories are injected.
- **Non-Production Scope**: Explicitly **not for production**—unsupported features (e.g., `UnitOfWork`, `merge`) make it unsuitable for persistence. Ideal for **test doubles** in **TDD** or **BDD** workflows.

### Integration Feasibility
- **Low Friction**: Can be **opt-in per test suite** via `phpunit.xml` or composer scripts, avoiding global impact.
- **Doctrine Dependency**: Requires `doctrine/annotations` and `doctrine/inflector` (peer dependencies), which may conflict with Laravel’s `doctrine/dbal` if not managed.
- **Entity Compatibility**:
  - Works **natively** with `@ORM\Entity` classes.
  - **Eloquent models** require wrapping in Doctrine entities or custom adapters.
- **Tooling Synergy**:
  - Complements **Laravel’s `RefreshDatabase`** for hybrid testing (e.g., use Doctrine Static for unit tests, DB for integration).
  - Integrates with **PHPUnit** via data providers or test traits.

### Technical Risk
- **Behavioral Gaps**:
  - **False confidence**: Tests may pass with mocks but fail in production due to unsupported Doctrine features (e.g., lifecycle callbacks).
  - **Edge cases**: Complex queries (e.g., `DQL`, `native SQL`) or cascading operations may not translate.
- **Maintenance Overhead**:
  - **Custom test data** must be manually seeded (vs. database fixtures).
  - **Test drift risk**: Mock data may diverge from production schema over time.
- **Performance**:
  - **Memory usage**: In-memory arrays scale poorly for **large datasets** (mitigate by resetting state per test).
  - **Cold starts**: Initialization overhead may slow down **parallel test suites**.

### Key Questions
1. **ORM Strategy**:
   - Is Laravel using **pure Eloquent**, **Doctrine**, or a **hybrid**? If Eloquent, evaluate if this package adds value beyond native mocks.
   - Are there **Doctrine-specific services** (e.g., custom repositories) that *must* be tested in isolation?
2. **Test Scope**:
   - Will this replace **database transactions** (e.g., SQLite) or supplement them for **repository-level tests**?
   - Are tests **unit-focused** (business logic) or **integration-focused** (API + DB)?
3. **Entity Complexity**:
   - Are entities **simple DTOs** or **rich with Doctrine behaviors** (e.g., `@PrePersist`, inheritance mapping)?
   - Do tests rely on **Doctrine events** (e.g., `postLoad`) or **metadata**?
4. **Tooling Ecosystem**:
   - How will this interact with **Laravel’s testing helpers** (e.g., `DatabaseMigrations`, `MakesHttpRequests`)?
   - Will it conflict with **existing mocking strategies** (e.g., `createMock`, `Mockery`)?
5. **Long-Term Viability**:
   - With **0 dependents** and **low stars**, is the package **actively maintained**? Consider:
     - Forking for Laravel-specific enhancements (e.g., Eloquent adapter).
     - Building a **Laravel-first alternative** (e.g., `laravel-doctrine-mocker`).
   - Does the **MIT license** align with your open-source policy?

---

## Integration Approach

### Stack Fit
- **Primary Use Case**:
  - **Unit/integration tests** for Doctrine repositories/services in Laravel.
  - **CI/CD acceleration**: Faster test execution by eliminating database setup.
- **Alternatives**:
  - **Eloquent**: Use Laravel’s native mocks (`createMock`) or `DatabaseTransactions`.
  - **Doctrine**: Leverage **Doctrine’s built-in interfaces** (`ObjectManager`, `Repository`) with `Mockery`.
  - **Hybrid**: Use **Doctrine Static for repositories** + **Eloquent mocks for models** in mixed stacks.
- **When to Avoid**:
  - **End-to-end tests**: Use **Pest/Dusk** or **Laravel HTTP tests** with a real DB.
  - **Database-specific behaviors**: Transactions, triggers, or stored procedures.

### Migration Path
1. **Assessment Phase**:
   - Audit **Doctrine-dependent tests** to identify candidates for migration.
   - Prioritize **high-impact, slow tests** (e.g., repository-heavy suites).
2. **Pilot Implementation**:
   - **Step 1**: Replace **1–2 critical test files** with Doctrine Static.
     Example:
     ```php
     // Before: DatabaseTransaction
     public function testFindUserByEmail() {
         $user = User::factory()->create(['email' => '[email protected]']);
         $this->assertEquals($user, User::where('email', '[email protected]')->first());
     }

     // After: DoctrineStatic
     public function testFindUserByEmail() {
         $registry = new ManagerRegistry([
             'default' => new ObjectManager([
                 new ObjectRepository(User::class, [
                     new User(1, '[email protected]')
                 ]),
             ]),
         ]);
         $user = $registry->getManager()->find(User::class, 1);
         $this->assertEquals('[email protected]', $user->getEmail());
     }
     ```
   - **Step 2**: Add a **custom test trait** for reuse:
     ```php
     trait UsesDoctrineStatic {
         protected ManagerRegistry $doctrine;

         protected function createDoctrineStatic(): void {
             $this->doctrine = new ManagerRegistry([
                 'default' => new ObjectManager([
                     new ObjectRepository(User::class, []),
                     new ObjectRepository(Post::class, []),
                 ]),
             ]);
         }

         protected function persistAndFlush(object $entity): void {
             $this->doctrine->getManager()->persist($entity);
             $this->doctrine->getManager()->flush();
         }
     }
     ```
3. **Incremental Rollout**:
   - **Phase 1**: Mock **simple CRUD** (`persist`, `find`, `findBy`).
   - **Phase 2**: Extend to **complex queries** (e.g., `findBy` with multiple conditions, joins).
   - **Phase 3**: Replace **database fixtures** with pre-populated mock arrays.
   - **Phase 4**: Integrate with **data factories** (e.g., `Faker`) for dynamic test data.

### Compatibility
- **Doctrine Entities**: **Zero changes** required—works with `@ORM\Entity` classes.
- **Laravel Eloquent**:
  - **Option 1**: Wrap Eloquent models in Doctrine entities for tests.
  - **Option 2**: Use **adapters** to bridge Eloquent and Doctrine Static (e.g., custom `ObjectRepository`).
- **Dependencies**:
  - **Required**: `doctrine/annotations`, `doctrine/inflector` (may conflict with Laravel’s `doctrine/dbal`).
  - **Mitigation**: Use **composer’s `replace`** or **aliases** to avoid conflicts.
  - **Optional**: `doctrine/orm` (only for type hints in tests; not runtime dependencies).
- **Laravel Services**:
  - **Doctrine-based services**: Directly replace `EntityManager` with `ManagerRegistry`.
  - **Eloquent-based services**: Mock dependencies at the **repository layer**.

### Sequencing
1. **Pre-requisites**:
   - Ensure **Doctrine Common** is installed (may require composer adjustments).
   - Add to `composer.json` under `require-dev`:
     ```json
     "dev-dependencies": {
         "benools/doctrine-static": "1.0.x-dev",
         "doctrine/annotations": "^2.0",
         "doctrine/inflector": "^2.0"
     }
     ```
2. **Test Isolation**:
   - Use **separate `phpunit.xml`** for Doctrine Static tests to avoid polluting the main suite.
     Example:
     ```xml
     <testsuites>
         <testsuite name="DoctrineStatic Tests">
             <directory>./tests/DoctrineStatic</directory>
         </testsuite>
         <testsuite name="Database Tests">
             <directory>./tests/Database</directory>
         </testsuite>
     </testsuites>
     ```
3. **CI/CD Integration**:
   - Add a **dedicated test stage** for Doctrine Static tests:
     ```yaml
     # .github/workflows/tests.yml
     jobs:
       test:
         runs-on: ubuntu-latest
         steps:
           - run: composer install
           - run: vendor/bin/phpunit --testsuite="DoctrineStatic"
     ```
4. **Hybrid Testing**:
   - Use **feature flags** to toggle between mock and real DB in tests:
     ```php
     if (config('testing.use_doctrine_static')) {
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.
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log