Skip to content

Commit

Permalink
Merge pull request #1039 from villfa/fix/mock-anonymous-classes
Browse files Browse the repository at this point in the history
Fix mocking with anonymous classes
  • Loading branch information
davedevelopment committed Feb 24, 2020
2 parents 30b93bb + 8809b17 commit 053393b
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 7 deletions.
10 changes: 6 additions & 4 deletions library/Mockery/Generator/DefinedTargetClass.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,22 @@
class DefinedTargetClass implements TargetClassInterface
{
private $rfc;
private $name;

public function __construct(\ReflectionClass $rfc)
public function __construct(\ReflectionClass $rfc, $alias = null)
{
$this->rfc = $rfc;
$this->name = $alias === null ? $rfc->getName() : $alias;
}

public static function factory($name)
public static function factory($name, $alias = null)
{
return new self(new \ReflectionClass($name));
return new self(new \ReflectionClass($name), $alias);
}

public function getName()
{
return $this->rfc->getName();
return $this->name;
}

public function isAbstract()
Expand Down
16 changes: 13 additions & 3 deletions library/Mockery/Generator/MockConfiguration.php
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,15 @@ public function getTargetClass()
}

if (class_exists($this->targetClassName)) {
$dtc = DefinedTargetClass::factory($this->targetClassName);
$alias = null;
if (strpos($this->targetClassName, '@') !== false) {
$alias = (new MockNameBuilder())
->addPart('anonymous_class')
->addPart(md5($this->targetClassName))
->build();
class_alias($this->targetClassName, $alias);
}
$dtc = DefinedTargetClass::factory($this->targetClassName, $alias);

if ($this->getTargetObject() == false && $dtc->isFinal()) {
throw new \Mockery\Exception(
Expand Down Expand Up @@ -419,11 +427,13 @@ public function generateName()
$nameBuilder = new MockNameBuilder();

if ($this->getTargetObject()) {
$nameBuilder->addPart(get_class($this->getTargetObject()));
$className = get_class($this->getTargetObject());
$nameBuilder->addPart(strpos($className, '@') !== false ? md5($className) : $className);
}

if ($this->getTargetClass()) {
$nameBuilder->addPart($this->getTargetClass()->getName());
$className = $this->getTargetClass()->getName();
$nameBuilder->addPart(strpos($className, '@') !== false ? md5($className) : $className);
}

foreach ($this->getTargetInterfaces() as $targetInterface) {
Expand Down
47 changes: 47 additions & 0 deletions tests/PHP70/MockingAnonymousClassTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php
/**
* Mockery
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://github.com/padraic/mockery/master/LICENSE
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to padraic@php.net so we can send you a copy immediately.
*
* @category Mockery
* @package Mockery
* @subpackage UnitTests
* @copyright Copyright (c) 2010 Pádraic Brady (http://blog.astrumfutura.com)
* @license http://github.com/padraic/mockery/blob/master/LICENSE New BSD License
*/

declare(strict_types=1); // Use strict types to ensure exact types are returned or passed

namespace test\Mockery;

use Mockery\Adapter\Phpunit\MockeryTestCase;

class MockingAnonymousClassTest extends MockeryTestCase
{
public function testMockFromAnonymousClassName()
{
$anonymousClassName = get_class(new class {});

$mock = mock($anonymousClassName);

$this->assertInstanceOf($anonymousClassName, $mock);
}

public function testMockFromAnonymousClassInstance()
{
$anonymousClass = new class {};

$mock = mock($anonymousClass);

$this->assertInstanceOf(get_class($anonymousClass), $mock);
}
}

0 comments on commit 053393b

Please sign in to comment.