2023-01-04 - Mocking repositories
INFO
This document represents an architecture decision record (ADR) and has been mirrored from the ADR section in our Shopware 6 repository. You can find the original version here
Context
Right now it is complicated to test classes which has a dependency on a repository. This is because mocking a repository search or searchIds call requires creating empty EntitySearchResults or IdSearchResults. This leads to much boilerplate code when writing tests and faking database results. For this reason we should provide a way to mock the search and searchIds calls in a much easier way.
Faking a search results of a repository looks like this at the moment:
$result = new EntitySearchResult(
'my-entity',
1,
new EntityCollection([]),
null,
new Criteria(),
Context::createDefaultContext()
);
$entityRepository = $this->createMock(EntityRepository::class);
$entityRepository
->expects(static::once())
->method('search')
->willReturn($result);Solution
We created a \Shopware\Tests\Unit\Common\Stubs\DataAbstractionLayer\StaticEntityRepository which allows the developer to easily fake repository search results.
How to use
<?php
class SomeCoreClass
{
public function __construct(private EntityRepository $repository) {}
public function foo()
{
$criteria = new Criteria();
$result = $this->repository->search($criteria, $context);
// ...
}
}
class SomeCoreClassTest extends TestCase
{
public function testFoo()
{
$repository = new StaticEntityRepository([
new UnitCollection([
new UnitEntity(),
new UnitEntity(),
])
]);
$class = new SomeCoreClass($repository);
$class->foo();
// some assertions
}
}The StaticEntityRepository constructor accepts an array of EntitySearchResults, EntityCollections or AggregationResultCollection. The value is the result of the search or one of the supported collections.
Other configurations
<?php
class SomeCoreClassTest extends TestCase
{
public function testFoo()
{
$repository = new StaticEntityRepository([
new UnitCollection([
new UnitEntity(),
]),
new AggregationResultCollection([
new AvgResult('some-aggregation', 12.0),
]),
new EntitySearchResult(
'entity',
1,
new EntityCollection(),
new AggregationResultCollection(),
new Criteria(),
Context::createDefaultContext()
),
[Uuid::randomHex(), Uuid::randomHex(), Uuid::randomHex()]
new IdSearchResult(0, [], new Criteria(), Context::createDefaultContext()),
]);
$class = new SomeCoreClass($repository);
$class->foo();
// some assertions
}
}