PHPackages                             ben-rowan/doctrine-assert - 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. ben-rowan/doctrine-assert

ActiveLibrary

ben-rowan/doctrine-assert
=========================

A collection of PHPUnit database assertions based on Doctrine2

v0.1.0(6y ago)031MITPHPPHP ^7.2

Since Aug 3Pushed 6y ago1 watchersCompare

[ Source](https://github.com/ben-rowan/doctrine-assert)[ Packagist](https://packagist.org/packages/ben-rowan/doctrine-assert)[ RSS](/packages/ben-rowan-doctrine-assert/feed)WikiDiscussions master Synced 2mo ago

READMEChangelog (1)Dependencies (9)Versions (2)Used By (0)

doctrine-assert
===============

[](#doctrine-assert)

A set of PHPUnit database assertions for your Doctrine entities.

Install
-------

[](#install)

```
composer require --dev ben-rowan/doctrine-assert
```

Usage
-----

[](#usage)

### Trait

[](#trait)

To add `doctrine-assert` to your tests you simply `use` the provided trait in your test class:

```
use DoctrineAssertTrait;
```

And implement a `getEntityManager(): EntityManager` method which allows the trait to access your tests entity manager.

You now have access to the following assertions.

### Assertions

[](#assertions)

All the database assertions require a root entity and a query config. The query config defines a number of joins taken from the root entity (zero or more) before then defining values for us to assert against.

For example:

```
$this->assertDatabaseHas(
    SomeEntity::class, //  [
                'active' => true
            ]
        ]
    ]
);
```

Here we can see that we're joining `AnotherEntity::class` to `SomeEntity:class`, then `YetAnotherEntity::class` to `AnotherEntity::class` before asserting that the value of `active` on `YetAnotherEntity::class` is `true` in one or more cases.

We can continue this nesting and joining as much as we need too including adding more than one join per entity.

```
$this->assertDatabaseHas(
    SomeEntity::class,
    [
        'active' => true,
        AnotherEntity::class => [
            'active' => true,
            YetAnotherEntity::class => [
                'active' => true
                // And we could just keep going if we needed to
            ]
        ],
        FinallyAnotherEntity::class => [
            'active' => true
        ]
    ]
);
```

Using this we can quickly and easily build up complex assertions against the current database state.

#### Database Has

[](#database-has)

Assert that the database has one or more entities that match the provided query config.

```
$this->assertDatabaseHas(
    SomeEntity::class,
    [
        'active' => true
    ]
);
```

#### Database Missing

[](#database-missing)

Assert that the database has zero entities that match the provided query config.

```
$this->assertDatabaseMissing(
    SomeEntity::class,
    [
        'active' => true
    ]
);
```

#### Database Count

[](#database-count)

Assert that the database has exactly `$count` entities that match the provided query config.

```
$this->assertDatabaseCount(
    100,  //  true
    ]
);
```

Testing
-------

[](#testing)

If you'd like to extend `doctrine-assert` or create a test case for a bug you've found then you'll need to be able to run the tests and create new ones.

### Running Tests

[](#running-tests)

Running the tests should be as simple as:

```
bash qa.bash
```

This will run:

- [PHPStan](https://github.com/phpstan/phpstan)
- [PHPMD](https://phpmd.org/)
- [PHPUnit](https://phpunit.de/)

If you'd also like to run the tests with [Infection](https://infection.github.io/)then use:

```
RUN_INFECTION='yes' bash qa.bash
```

You'll need to have [XDebug](https://xdebug.org/) installed for this to work though as it requires coverage to be generated.

### Testing Framework

[](#testing-framework)

*Feel free to skip this section and move straight on to '[Creating New Tests](https://github.com/ben-rowan/doctrine-assert#creating-new-tests)'*

#### The Problem

[](#the-problem)

In order to test the library we need to generate a large number of entities as well as create the associated database schema. To keep the code self contained and save committing large numbers of test entities into the code base we make use of the virtual file system [vfs://stream](http://vfs.bovigo.org/) and [sqlite](https://sqlite.org/index.html). This has the added side benefit of running everything in RAM making the test suite run as fast as possible.

#### How The Testing Framework Works

[](#how-the-testing-framework-works)

The following process takes place before each test is run and is managed by [`AbstractDoctrineAssertTest`](./tests/AbstractDoctrineAssertTest.php).

##### Virtual File System

[](#virtual-file-system)

We first initialise the [virtual file system](http://vfs.bovigo.org/) before copying over the Doctrine [YAML mapping](https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/yaml-mapping.html)files that we'll later use to generate our test entities.

##### Entity Manager

[](#entity-manager)

Now we setup the entity manager with our YAML mapping config and an in memory SQLite database. The database is recreated before each test run making sure we have no leakage between tests.

##### Generate Entities

[](#generate-entities)

After we've setup the entity manager we can use it's meta data and an [`EntityGenerator`](https://github.com/doctrine/orm/blob/2.6/lib/Doctrine/ORM/Tools/EntityGenerator.php)to create the tests entities. Before we can use these we also need to loop through and require them.

##### Update Schema

[](#update-schema)

Finally we update the database schema to match our entities and we're good to go.

### Test Structure

[](#test-structure)

```
DoubleOneToOne
├── AssertDatabaseCountTest.php
├── AssertDatabaseHasTest.php
├── AssertDatabaseMissingTest.php
└── Vfs
    └── config
        ├── Vfs.DoubleOneToOne.One.dcm.yml
        ├── Vfs.DoubleOneToOne.Two.dcm.yml
        └── Vfs.DoubleOneToOne.Three.dcm.yml

```

Tests are structured based on the types of entities they'd like to test against, all tests using the same set of entities are stored in a directory, in this case `DoubleOneToOne`. This way we can minimise the number of entity sets that we need to define.

Next we have the virtual file system `Vfs/` that will be used by any tests within this folder. Within `Vfs/config` we define our test entities using Doctrine's [YAML Mapping](https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/yaml-mapping.html) format. The YAML filename should match the class name defined inside so `Vfs\DoubleOneToOne\One`becomes `Vfs.DoubleOneToOne.One` with `.dcm.yml` on the end `Vfs.DoubleOneToOne.One.dcm.yml`.

### Creating A Test

[](#creating-a-test)

Here's the basic outline of a test.

```
class YourTest extends AbstractDoctrineAssertTest
{
    public const VFS_NAMESPACE = 'Vfs\\YourTest\\';

    use DoctrineAssertTrait;

    protected function getVfsPath(): string
    {
        return __DIR__ . '/Vfs';
    }

    public function setUp()
    {
        parent::setUp();

        $this->createEntities();
    }

    public function testSomethingPasses(): void
    {
        $this->assertDatabaseHas(
            self::VFS_NAMESPACE . 'One',
            [
                'test' => 'passes'
            ]
        );
    }

    public function testSomethingFails(): void
    {
        $this->expectException(ExpectationFailedException::class);

        $this->assertDatabaseHas(
            self::VFS_NAMESPACE . 'One',
            [
                'test' => 'fails'
            ]
        );
    }

    private function createEntities(): void
    {
        $generator = Factory::create();
        $populator = new Populator($generator, $this->getEntityManager());

        $populator->addEntity(self::VFS_NAMESPACE . 'One', 1,
            [
                'test' => 'passes'
            ]
        );

        // ...

        $populator->execute();
    }
}
```

#### Define Entities

[](#define-entities)

If the entities that we need for our test don't already exist then we create a directory for our tests and YAML files that define all the entities our test will require. If the entities do exist then we can simply add our new test to that directory.

#### Create Test Class

[](#create-test-class)

Now we create a test class. The class *must* extend [`AbstractDoctrineAssertTest`](./tests/AbstractDoctrineAssertTest.php).

You'll also want to `use`[`DoctrineAssertTrait`](https://github.com/ben-rowan/doctrine-assert/blob/master/src/DoctrineAssertTrait.php)so that you can make test assertions with it.

#### Create Test Method

[](#create-test-method)

We now create one method for each item we'd like to test (as normal).

#### Setup Fixture Data

[](#setup-fixture-data)

You can setup the fixture data you require for your test using [Fakers generators and populators](https://github.com/fzaninotto/Faker#populating-entities-using-an-orm-or-an-odm).

```
$generator = Factory::create();
$populator = new Populator($generator, $this->getEntityManager());

$populator->addEntity(self::VFS_NAMESPACE . 'Three', 1,
    [
        'name' => 'Three'
    ]
);

// ...

$populator->execute();
```

#### Make Assertion

[](#make-assertion)

Finally you'll use to the `doctrine-assert` assertions to make an assertion. If you'd like to test that an assertion correctly fails then you can simply expect the `ExpectationFailedException`.

```
$this->expectException(ExpectationFailedException::class);
```

###  Health Score

20

—

LowBetter than 14% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity4

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity43

Maturing project, gaining track record

 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

Unknown

Total

1

Last Release

2472d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/f7b5680736c57c261b7305a1c9a4e9e0499c209f77abef4e92892b4ecefb7dc6?d=identicon)[ben-rowan](/maintainers/ben-rowan)

---

Top Contributors

[![ben-rowan](https://avatars.githubusercontent.com/u/8903653?v=4)](https://github.com/ben-rowan "ben-rowan (46 commits)")

###  Code Quality

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/ben-rowan-doctrine-assert/health.svg)

```
[![Health](https://phpackages.com/badges/ben-rowan-doctrine-assert/health.svg)](https://phpackages.com/packages/ben-rowan-doctrine-assert)
```

###  Alternatives

[sylius/sylius

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

8.4k5.6M648](/packages/sylius-sylius)[sulu/sulu

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

1.3k1.3M152](/packages/sulu-sulu)[prestashop/prestashop

PrestaShop is an Open Source e-commerce platform, committed to providing the best shopping cart experience for both merchants and customers.

9.0k15.4k](/packages/prestashop-prestashop)[hautelook/alice-bundle

Symfony bundle to manage fixtures with Alice and Faker.

19519.4M34](/packages/hautelook-alice-bundle)[lchrusciel/api-test-case

Perfect PHPUnit TestCase for JSON/XML API TDD with Symfony.

4115.5M63](/packages/lchrusciel-api-test-case)[contao/core-bundle

Contao Open Source CMS

1231.6M2.3k](/packages/contao-core-bundle)

PHPackages © 2026

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