Skip to content

Commit

Permalink
Simplify Factory test by utilising a PSR container stub
Browse files Browse the repository at this point in the history
Signed-off-by: George Steel <[email protected]>
  • Loading branch information
gsteel committed Jan 8, 2024
1 parent 5c4b7b4 commit d73ad7b
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 49 deletions.
57 changes: 8 additions & 49 deletions test/AppTest/Handler/HomePageHandlerFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,73 +6,32 @@

use App\Handler\HomePageHandler;
use App\Handler\HomePageHandlerFactory;
use AppTest\InMemoryContainer;
use Mezzio\Router\RouterInterface;
use Mezzio\Template\TemplateRendererInterface;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Container\ContainerInterface;

use function in_array;

class HomePageHandlerFactoryTest extends TestCase
{
/** @var ContainerInterface&MockObject */
protected $container;

/** @var RouterInterface&MockObject */
protected $router;

protected function setUp(): void
{
$this->container = $this->createMock(ContainerInterface::class);
$this->router = $this->createMock(RouterInterface::class);
}

public function testFactoryWithoutTemplate(): void
{
$this->container
->expects($this->once())
->method('has')
->with(TemplateRendererInterface::class)
->willReturn(false);
$this->container
->expects($this->once())
->method('get')
->with(RouterInterface::class)
->willReturn($this->router);
$container = new InMemoryContainer();
$container->setService(RouterInterface::class, $this->createMock(RouterInterface::class));

$factory = new HomePageHandlerFactory();
$homePage = $factory($this->container);
$homePage = $factory($container);

self::assertInstanceOf(HomePageHandler::class, $homePage);
}

public function testFactoryWithTemplate(): void
{
$renderer = $this->createMock(TemplateRendererInterface::class);
$this->container
->expects($this->once())
->method('has')
->with(TemplateRendererInterface::class)
->willReturn(true);
$this->container
->expects($this->exactly(2))
->method('get')
->with(self::callback(static function (string $name): bool {
self::assertTrue(in_array($name, [
RouterInterface::class,
TemplateRendererInterface::class,
]));

return true;
}))
->willReturnOnConsecutiveCalls(
$this->router,
$renderer
);
$container = new InMemoryContainer();
$container->setService(RouterInterface::class, $this->createMock(RouterInterface::class));
$container->setService(TemplateRendererInterface::class, $this->createMock(TemplateRendererInterface::class));

$factory = new HomePageHandlerFactory();
$homePage = $factory($this->container);
$homePage = $factory($container);

self::assertInstanceOf(HomePageHandler::class, $homePage);
}
Expand Down
47 changes: 47 additions & 0 deletions test/AppTest/InMemoryContainer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

declare(strict_types=1);

namespace AppTest;

use Psr\Container\ContainerInterface;
use RuntimeException;

use function array_key_exists;
use function sprintf;

/**
* A PSR Container stub. Useful for testing factories without excessive mocking
*/
class InMemoryContainer implements ContainerInterface
{
/** @var array<string, mixed> */
public array $services = [];

public function setService(string $name, mixed $service): void
{
$this->services[$name] = $service;
}

/**
* @param string $id
* @return mixed
*/
public function get($id)
{
if (! $this->has($id)) {
throw new RuntimeException(sprintf('Service not found "%s"', $id));
}

return $this->services[$id];
}

/**
* @param string $id
* @return bool
*/
public function has($id)
{
return array_key_exists($id, $this->services);
}
}

0 comments on commit d73ad7b

Please sign in to comment.