Skip to content

Instantly share code, notes, and snippets.

@domagoj03
Forked from DragonBe/FinalClass.php
Created July 16, 2018 12:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save domagoj03/50aa0713dde8d57048afd331a769d812 to your computer and use it in GitHub Desktop.
Save domagoj03/50aa0713dde8d57048afd331a769d812 to your computer and use it in GitHub Desktop.
Testing final classes is tricky, but possible even though you cannot directly mock a "final" class
<?php
namespace FinalClass;
require_once __DIR__ . '/vendor/autoload.php';
use PHPUnit\Framework\TestCase;
final class Foo
{
protected $bar;
public function __construct(BarInterface $bar)
{
$this->bar = $bar;
}
public function bar()
{
return 'Hello ' . $this->bar->getMessage() . '!';
}
}
interface BarInterface {}
final class Bar implements BarInterface
{
protected $message;
public function __construct()
{
$this->message = 'World';
}
public function getMessage()
{
return $this->message;
}
}
class BarMock implements BarInterface
{
protected $bar;
public function __construct()
{
$this->bar = new \ReflectionClass(Bar::class);
}
public function __call($name, $args)
{
$bar = $this->bar->newInstance($args);
return $bar->$name();
}
}
class FooTest extends TestCase
{
public function testFooReturnsMessage()
{
$bar = $this->getMockBuilder(BarMock::class)
->setMethods(['getMessage'])
->getMock();
$bar->expects($this->once())
->method('getMessage')
->willReturn('World');
$foo = new Foo($bar);
$this->assertSame('Hello World!', $foo->bar());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment