PHPackages                             firehed/mocktrine - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Testing &amp; Quality](/categories/testing)
4. /
5. firehed/mocktrine

ActiveLibrary[Testing &amp; Quality](/categories/testing)

firehed/mocktrine
=================

PHPUnit Doctrine mocking tools

3.0.0(1w ago)415.9k↑38.2%[7 issues](https://github.com/Firehed/mocktrine/issues)[6 PRs](https://github.com/Firehed/mocktrine/pulls)MITPHPPHP ^8.2CI passing

Since Oct 8Pushed 1w agoCompare

[ Source](https://github.com/Firehed/mocktrine)[ Packagist](https://packagist.org/packages/firehed/mocktrine)[ RSS](/packages/firehed-mocktrine/feed)WikiDiscussions main Synced 3d ago

READMEChangelog (8)Dependencies (24)Versions (25)Used By (0)

Mocktrine
=========

[](#mocktrine)

An in-memory Doctrine mocking library for testing

[![Latest Stable Version](https://camo.githubusercontent.com/d49a5f0f837f2ef85cc7c245470cf17b0b1fe32a801cab74c4358e97e1fba44b/68747470733a2f2f706f7365722e707567782e6f72672f666972656865642f6d6f636b7472696e652f76)](//packagist.org/packages/firehed/mocktrine)[![License](https://camo.githubusercontent.com/1f192963ce129f09f47f58bbb6661193ca9c806bddcc5e452f14b9b75e405b58/68747470733a2f2f706f7365722e707567782e6f72672f666972656865642f6d6f636b7472696e652f6c6963656e7365)](//packagist.org/packages/firehed/mocktrine)[![Test](https://github.com/Firehed/mocktrine/workflows/Test/badge.svg)](https://github.com/Firehed/mocktrine/actions?query=workflow%3ATest)[![Static analysis](https://github.com/Firehed/mocktrine/workflows/Static%20analysis/badge.svg)](https://github.com/Firehed/mocktrine/actions?query=workflow%3A%22Static+analysis%22)[![Lint](https://github.com/Firehed/mocktrine/workflows/Lint/badge.svg)](https://github.com/Firehed/mocktrine/actions?query=workflow%3ALint)

Mocktrine lets you write unit and integration tests with your real Doctrine models and a real EntityManagerInterfae, without brittle mocks of EntityManagerInterface methods. Work with data as if it was already in your database, and things should Just Work.

Quick Start
-----------

[](#quick-start)

In your unit tests that need an Entity Manager, use a `new \Firehed\Mocktrine\InMemoryEntityManager`. Done!

Any object with Doctrine's entity attributes (`#[Entity]`, `#[Id]`, `#[Column]`, etc) should work without modification. Create, update, and retrieve entities without a database connection. `#[GeneratedValue]` ids will get populated on their initial `flush()`, just like your real database will do.

This library aims to provide as much type information as possible, so that static analysis tools (such as PHPStan) work well without additional plugins.

Recommended Usage
-----------------

[](#recommended-usage)

This library works best when setup in a trait alongside other utility functions:

```
trait TestTools
{
    private ?EntityManagerInterface $em = null;

    public function getEntityManager(): EntityManagerInterface
    {
        if ($this->em === null) {
            $this->em = new Mocktrine(new AttributeDriver(['path/to/entites']));
        }
        return $this->em;
    }

    private function addPersistedEntity(object $entity): void
    {
        $em = $this->getEntityManager();
        $em->persist($entity);
        $em->flush(); // To assign PK, if needed
    }

    // Application-specific examples
    public function createUser(): User
    {
        $user = new User();
        $this->addPersistedEntity($user);
        return $user;
    }

    public function createGroup(
        ?User $owner = null,
    ): Group {
        $owner ??= $this->createUser();
        $group = new Group(owner: $owner);
        $this->addPersistedEntity($group);
        return $group;
    }
}
```

```
class GroupServiceTests extends TestCase
{
    use TestTools;

    public function testCreate(): void
    {
        $service = new GroupService($this->getEntityManager());

        $owner = $this->createUser();
        $group = $service->createGroup(owner: $owner);
        self::assertSame($owner->id, $group->ownerId, 'Owner assignment failed');
    }

    public function testEdit(): void
    {
        $service = new GroupService($this->getEntityManager());
        $group = $this->createGroup();

        $service->updateGroup($group, [
            'name' => 'The Name',
        ]);

        self::assertSame('The Name', $group->name);
    }
}
```

Supported ORM Features
----------------------

[](#supported-orm-features)

The following methods on Doctrine's `EntityManagerInterface` should all work as expected:

- find
- persist
- remove
- flush
- getRepository
- getCache (will always return `null`)
- isOpen (will always return `true`)

All methods on the `ObjectRepository` (for various findBy operations) should also work, as well as the non-interface `count($criteria)` method. `ObjectRepository` also implements the `Selectable` interface (as `EntityRepository` does, which is the returned type from `EntityManager`), so it's also possible to use the `matching(Criteria)` method.

The following methods are **not** supported at this time:

- clear
- detach
- refresh
- getClassMetadata
- getMetadataFactory
- initializeObject
- contains
- getConnection
- getExpressionBuilder
- beginTransaction
- wrapInTransaction
- commit
- rollback
- createQuery
- createNativeQuery
- getReference
- close
- lock
- getEventManager
- getConfiguration
- getUnitOfWork
- newHydrator
- getProxyFactory
- getFilters
- isFiltersStateClean
- hasFilters

Mapping support
---------------

[](#mapping-support)

If a MappingDriver is not provided to the `InMemoryEntityManager`, it will default to `AttributeDriver`. It is STRONGLY RECOMMENDED to always pass the same driver you use in your real application:

```
$em = new \Firehed\Mocktrine\InMemoryEntityManager(
    new \Doctrine\ORM\Mapping\Driver\AttributeDriver(['src/Model']),
 );
```

You can also grab the value directly from your Doctrine config:

```
$config = ORMSetup::createAttributeMetadataConfiguration(...);
$driver = $config->getMetadataDriverImpl();
$em = new Firehed\Mocktrine\InMemoryEntityManager($driver);
```

Why Mocktrine?
--------------

[](#why-mocktrine)

### vs SQLite/MySQL/Postgres

[](#vs-sqlitemysqlpostgres)

1. Speed. Mocktrine tests run entirely in-memory with no database server, connection overhead, or schema setup. This makes them orders of magnitude faster — enabling hundreds or thousands of tests per second.
2. Isolation. Every test gets a clean "database", so you can precisely control workflows and test scenarios. No phantom bugs from a previous run.

Mocktrine excels when testing business logic that involves an EntityManager: services, handlers, API internals, repositories, and more.

### vs mocking `EntityManagerInterface`

[](#vs-mocking-entitymanagerinterface)

1. Avoid boilerplate. Mocktrine was created out of internal tools that existed to make mocking less painful across thousands of tests.
2. Flexibility. Mocks, especially for EntityManager, are often brittle - specific find/findBy/getRepository/... paths that can break on refactors or mask incorrect logic. Mocktrine resolves everything and checks real data.

### Differences from a real database and ORM connection

[](#differences-from-a-real-database-and-orm-connection)

- Not all ORM methods are supported (see above)
- You *may* get subtle differences with case-sensitivity and sorting (this depends on the real database and collation settings)
- The EM doesn't close on error (mostly because there are no network errors to be had)

Mocktrine *complements* real-database integration and end-to-end tests, not replaces them. Use it for the common case of testing business logic, and supplement it with real-database tests for persistence, custom queries, advanced reporting, and more.

###  Health Score

55

—

FairBetter than 97% of packages

Maintenance78

Regular maintenance activity

Popularity29

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity85

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~391 days

Recently: every ~445 days

Total

11

Last Release

11d ago

Major Versions

0.8.0 → 3.0.02026-06-23

PHP version history (2 changes)0.3.0PHP ^7.4 || ^8.0

0.8.0PHP ^8.2

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/354842?v=4)[Eric Stern](/maintainers/Firehed)[@Firehed](https://github.com/Firehed)

---

Top Contributors

[![Firehed](https://avatars.githubusercontent.com/u/354842?v=4)](https://github.com/Firehed "Firehed (50 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP\_CodeSniffer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/firehed-mocktrine/health.svg)

```
[![Health](https://phpackages.com/badges/firehed-mocktrine/health.svg)](https://phpackages.com/packages/firehed-mocktrine)
```

###  Alternatives

[sylius/sylius

E-Commerce platform for PHP, based on Symfony framework.

8.5k5.9M738](/packages/sylius-sylius)[oro/platform

Business Application Platform (BAP)

645143.5k115](/packages/oro-platform)[sulu/sulu

Core framework that implements the functionality of the Sulu content management system

1.3k1.4M204](/packages/sulu-sulu)[open-dxp/opendxp

Content &amp; Product Management Framework (CMS/PIM)

9421.6k61](/packages/open-dxp-opendxp)[contao/core-bundle

Contao Open Source CMS

1231.6M2.8k](/packages/contao-core-bundle)[api-platform/doctrine-common

Common files used by api-platform/doctrine-orm and api-platform/doctrine-odm

274.4M48](/packages/api-platform-doctrine-common)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
