Skip to content

Commit

Permalink
Closes #5535
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastianbergmann committed Oct 18, 2023
1 parent 5a24ff8 commit db9ae30
Show file tree
Hide file tree
Showing 76 changed files with 236 additions and 8 deletions.
1 change: 1 addition & 0 deletions ChangeLog-11.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ All notable changes of the PHPUnit 11.0 release series are documented in this fi
* [#5421](https://github.com/sebastianbergmann/phpunit/issues/5421): `MockBuilder::enableAutoReturnValueGeneration()` and `MockBuilder::disableAutoReturnValueGeneration()` (these methods were already [soft-deprecated](https://phpunit.de/backward-compatibility.html#soft-deprecation) in PHPUnit 10)
* [#5423](https://github.com/sebastianbergmann/phpunit/issues/5423): `TestCase::returnValue()`, `TestCase::onConsecutiveCalls()`, `TestCase::returnValueMap()`, `TestCase::returnArgument()`, `TestCase::returnSelf()`, and `TestCase::returnCallback()` (these methods were already [soft-deprecated](https://phpunit.de/backward-compatibility.html#soft-deprecation) in PHPUnit 10)
* [#5472](https://github.com/sebastianbergmann/phpunit/issues/5472): `assertStringNotMatchesFormat()` and `assertStringNotMatchesFormatFile()` (these methods were already [soft-deprecated](https://phpunit.de/backward-compatibility.html#soft-deprecation) in PHPUnit 10)
* [#5535](https://github.com/sebastianbergmann/phpunit/issues/5535): Configuring expectations using `expects()` on test stubs

### Removed

Expand Down
1 change: 1 addition & 0 deletions DEPRECATIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ This functionality is currently [hard-deprecated](https://phpunit.de/backward-co
| [#5423](https://github.com/sebastianbergmann/phpunit/issues/5423) | `TestCase::returnSelf()` | 10.3.0 | Use `$double->willReturnSelf()` instead of `$double->will($this->returnSelf())` |
| [#5423](https://github.com/sebastianbergmann/phpunit/issues/5423) | `TestCase::returnValue()` | 10.3.0 | Use `$double->willReturn()` instead of `$double->will($this->returnValue())` |
| [#5423](https://github.com/sebastianbergmann/phpunit/issues/5423) | `TestCase::returnValueMap()` | 10.3.0 | Use `$double->willReturnMap()` instead of `$double->will($this->returnValueMap())` |
| [#5535](https://github.com/sebastianbergmann/phpunit/issues/5525) | Configuring expectations using `expects()` on test stubs | 11.0.0 | Create a mock object when you need to configure expectations on a test double |

#### Miscellaneous

Expand Down
21 changes: 17 additions & 4 deletions src/Framework/MockObject/Generator/Generator.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@
use PHPUnit\Framework\InvalidArgumentException;
use PHPUnit\Framework\MockObject\ConfigurableMethod;
use PHPUnit\Framework\MockObject\DoubledCloneMethod;
use PHPUnit\Framework\MockObject\GeneratedAsMockObject;
use PHPUnit\Framework\MockObject\GeneratedAsTestStub;
use PHPUnit\Framework\MockObject\Method;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\MockObject\MockObjectApi;
Expand Down Expand Up @@ -106,7 +108,7 @@ final class Generator
* @throws RuntimeException
* @throws UnknownTypeException
*/
public function testDouble(string $type, bool $mockObject, ?array $methods = [], array $arguments = [], string $mockClassName = '', bool $callOriginalConstructor = true, bool $callOriginalClone = true, bool $callAutoload = true, bool $cloneArguments = true, bool $callOriginalMethods = false, object $proxyTarget = null, bool $allowMockingUnknownTypes = true, bool $returnValueGeneration = true): MockObject|Stub
public function testDouble(string $type, bool $mockObject, bool $markAsMockObject, ?array $methods = [], array $arguments = [], string $mockClassName = '', bool $callOriginalConstructor = true, bool $callOriginalClone = true, bool $callAutoload = true, bool $cloneArguments = true, bool $callOriginalMethods = false, object $proxyTarget = null, bool $allowMockingUnknownTypes = true, bool $returnValueGeneration = true): MockObject|Stub
{
if ($type === Traversable::class) {
$type = Iterator::class;
Expand All @@ -126,6 +128,7 @@ public function testDouble(string $type, bool $mockObject, ?array $methods = [],
$mock = $this->generate(
$type,
$mockObject,
$markAsMockObject,
$methods,
$mockClassName,
$callOriginalClone,
Expand Down Expand Up @@ -213,7 +216,7 @@ public function testDoubleForInterfaceIntersection(array $interfaces, bool $mock

eval($template->render());

return $this->testDouble($intersectionName, $mockObject);
return $this->testDouble($intersectionName, $mockObject, $mockObject);
}

/**
Expand Down Expand Up @@ -257,6 +260,7 @@ interface_exists($originalClassName, $callAutoload)) {
$mockObject = $this->testDouble(
$originalClassName,
true,
true,
$methods,
$arguments,
$mockClassName,
Expand Down Expand Up @@ -381,12 +385,13 @@ public function objectForTrait(string $traitName, string $traitClassName = '', b
*
* @see https://github.com/sebastianbergmann/phpunit/issues/5476
*/
public function generate(string $type, bool $mockObject, array $methods = null, string $mockClassName = '', bool $callOriginalClone = true, bool $callAutoload = true, bool $cloneArguments = true, bool $callOriginalMethods = false): MockClass
public function generate(string $type, bool $mockObject, bool $markAsMockObject, array $methods = null, string $mockClassName = '', bool $callOriginalClone = true, bool $callAutoload = true, bool $cloneArguments = true, bool $callOriginalMethods = false): MockClass
{
if ($mockClassName !== '') {
return $this->generateCodeForTestDoubleClass(
$type,
$mockObject,
$markAsMockObject,
$methods,
$mockClassName,
$callOriginalClone,
Expand All @@ -399,6 +404,7 @@ public function generate(string $type, bool $mockObject, array $methods = null,
$key = md5(
$type .
($mockObject ? 'MockObject' : 'TestStub') .
($markAsMockObject ? 'MockObject' : 'TestStub') .
serialize($methods) .
serialize($callOriginalClone) .
serialize($cloneArguments) .
Expand All @@ -409,6 +415,7 @@ public function generate(string $type, bool $mockObject, array $methods = null,
self::$cache[$key] = $this->generateCodeForTestDoubleClass(
$type,
$mockObject,
$markAsMockObject,
$methods,
$mockClassName,
$callOriginalClone,
Expand Down Expand Up @@ -587,7 +594,7 @@ private function getObject(MockType $mockClass, string $type = '', bool $callOri
* @throws ReflectionException
* @throws RuntimeException
*/
private function generateCodeForTestDoubleClass(string $type, bool $mockObject, ?array $explicitMethods, string $mockClassName, bool $callOriginalClone, bool $callAutoload, bool $cloneArguments, bool $callOriginalMethods): MockClass
private function generateCodeForTestDoubleClass(string $type, bool $mockObject, bool $markAsMockObject, ?array $explicitMethods, string $mockClassName, bool $callOriginalClone, bool $callAutoload, bool $cloneArguments, bool $callOriginalMethods): MockClass
{
$classTemplate = $this->loadTemplate('test_double_class.tpl');
$additionalInterfaces = [];
Expand Down Expand Up @@ -743,6 +750,12 @@ private function generateCodeForTestDoubleClass(string $type, bool $mockObject,
$traits[] = MockObjectApi::class;
}

if ($markAsMockObject) {
$traits[] = GeneratedAsMockObject::class;
} else {
$traits[] = GeneratedAsTestStub::class;
}

if ($mockMethods->hasMethod('method') || (isset($class) && $class->hasMethod('method'))) {
$message = 'Doubling interfaces (or classes) that have a method named "method" is deprecated. Support for this will be removed in PHPUnit 12.';

Expand Down
1 change: 1 addition & 0 deletions src/Framework/MockObject/MockBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ public function getMock(): MockObject
$object = $this->generator->testDouble(
$this->type,
true,
true,
!$this->emptyMethodsArray ? $this->methods : null,
$this->constructorArgs,
$this->mockClassName ?? '',
Expand Down
21 changes: 21 additions & 0 deletions src/Framework/MockObject/Runtime/Api/GeneratedAsMockObject.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php declare(strict_types=1);
/*
* This file is part of PHPUnit.
*
* (c) Sebastian Bergmann <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace PHPUnit\Framework\MockObject;

/**
* @internal This trait is not covered by the backward compatibility promise for PHPUnit
*/
trait GeneratedAsMockObject
{
public function __phpunit_wasGeneratedAsMockObject(): true
{
return true;
}
}
21 changes: 21 additions & 0 deletions src/Framework/MockObject/Runtime/Api/GeneratedAsTestStub.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php declare(strict_types=1);
/*
* This file is part of PHPUnit.
*
* (c) Sebastian Bergmann <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace PHPUnit\Framework\MockObject;

/**
* @internal This trait is not covered by the backward compatibility promise for PHPUnit
*/
trait GeneratedAsTestStub
{
public function __phpunit_wasGeneratedAsMockObject(): false
{
return false;
}
}
28 changes: 28 additions & 0 deletions src/Framework/MockObject/Runtime/Api/MockObjectApi.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,20 @@
*/
namespace PHPUnit\Framework\MockObject;

use function assert;
use PHPUnit\Event\Code\NoTestCaseObjectOnCallStackException;
use PHPUnit\Event\Code\TestMethodBuilder;
use PHPUnit\Event\Facade as EventFacade;
use PHPUnit\Framework\MockObject\Builder\InvocationMocker as InvocationMockerBuilder;
use PHPUnit\Framework\MockObject\Rule\AnyInvokedCount;
use PHPUnit\Framework\MockObject\Rule\InvocationOrder;

/**
* @internal This trait is not covered by the backward compatibility promise for PHPUnit
*/
trait MockObjectApi
{
private static array $__phpunit_deprecation_emitted_for_test = [];
private object $__phpunit_originalObject;

/** @noinspection MagicMethodsValidityInspection */
Expand Down Expand Up @@ -47,6 +53,28 @@ abstract public function __phpunit_unsetInvocationMocker(): void;

public function expects(InvocationOrder $matcher): InvocationMockerBuilder
{
assert($this instanceof StubInternal);

if (!$matcher instanceof AnyInvokedCount &&
!$this->__phpunit_wasGeneratedAsMockObject()) {
$message = 'Configuring expectations on test doubles that were created as test stubs is deprecated. Support for this will be removed in PHPUnit 12.';

try {
$test = TestMethodBuilder::fromCallStack();

if (!isset(self::$__phpunit_deprecation_emitted_for_test[$test->id()])) {
EventFacade::emitter()->testTriggeredPhpunitDeprecation(
$test,
$message,
);

self::$__phpunit_deprecation_emitted_for_test[$test->id()] = true;
}
} catch (NoTestCaseObjectOnCallStackException) {
EventFacade::emitter()->testRunnerTriggeredDeprecation($message);
}
}

return $this->__phpunit_getInvocationHandler()->expects($matcher);
}
}
2 changes: 2 additions & 0 deletions src/Framework/MockObject/Runtime/Interface/StubInternal.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,6 @@ public function __phpunit_getInvocationHandler(): InvocationHandler;
public function __phpunit_setReturnValueGeneration(bool $returnValueGeneration): void;

public function __phpunit_unsetInvocationMocker(): void;

public function __phpunit_wasGeneratedAsMockObject(): bool;
}
2 changes: 1 addition & 1 deletion src/Framework/MockObject/Runtime/ReturnValueGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ private function newInstanceOf(string $stubClassName, string $className, string
private function testDoubleFor(string $type, string $className, string $methodName): Stub
{
try {
return (new Generator)->testDouble($type, false, [], [], '', false);
return (new Generator)->testDouble($type, false, false, [], [], '', false);
} catch (Throwable $t) {
throw new RuntimeException(
sprintf(
Expand Down
3 changes: 3 additions & 0 deletions src/Framework/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -1244,6 +1244,7 @@ final protected function createMock(string $originalClassName): MockObject
$mock = (new MockGenerator)->testDouble(
$originalClassName,
true,
true,
callOriginalConstructor: false,
callOriginalClone: false,
cloneArguments: false,
Expand Down Expand Up @@ -1443,6 +1444,7 @@ final protected function getMockFromWsdl(string $wsdlFile, string $originalClass
$mockObject = (new MockGenerator)->testDouble(
$originalClassName,
true,
true,
$methods,
['', $options],
$mockClassName,
Expand Down Expand Up @@ -2284,6 +2286,7 @@ final protected static function createStub(string $originalClassName): Stub
$stub = (new MockGenerator)->testDouble(
$originalClassName,
true,
false,
callOriginalConstructor: false,
callOriginalClone: false,
cloneArguments: false,
Expand Down
2 changes: 2 additions & 0 deletions tests/end-to-end/mock-objects/generator/232.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ $generator = new \PHPUnit\Framework\MockObject\Generator\Generator;
$mock = $generator->generate(
'Foo',
true,
true,
[],
'MockFoo',
true,
Expand All @@ -59,6 +60,7 @@ class MockFoo extends Foo implements PHPUnit\Framework\MockObject\MockObjectInte
{
use PHPUnit\Framework\MockObject\StubApi;
use PHPUnit\Framework\MockObject\MockObjectApi;
use PHPUnit\Framework\MockObject\GeneratedAsMockObject;
use PHPUnit\Framework\MockObject\Method;
use PHPUnit\Framework\MockObject\DoubledCloneMethod;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ $generator = new \PHPUnit\Framework\MockObject\Generator\Generator;
$mock = $generator->generate(
Issue3154::class,
true,
true,
[],
'Issue3154Mock',
true,
Expand All @@ -44,6 +45,7 @@ class Issue3154Mock extends Is\Namespaced\Issue3154 implements PHPUnit\Framework
{
use PHPUnit\Framework\MockObject\StubApi;
use PHPUnit\Framework\MockObject\MockObjectApi;
use PHPUnit\Framework\MockObject\GeneratedAsMockObject;
use PHPUnit\Framework\MockObject\Method;
use PHPUnit\Framework\MockObject\DoubledCloneMethod;

Expand Down
2 changes: 2 additions & 0 deletions tests/end-to-end/mock-objects/generator/3967.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ $generator = new \PHPUnit\Framework\MockObject\Generator\Generator;
$mock = $generator->generate(
'Baz',
true,
true,
[],
'MockBaz',
true,
Expand All @@ -32,6 +33,7 @@ class MockBaz extends Exception implements Baz, PHPUnit\Framework\MockObject\Moc
{
use PHPUnit\Framework\MockObject\StubApi;
use PHPUnit\Framework\MockObject\MockObjectApi;
use PHPUnit\Framework\MockObject\GeneratedAsMockObject;
use PHPUnit\Framework\MockObject\Method;
use PHPUnit\Framework\MockObject\ProxiedCloneMethod;

Expand Down
2 changes: 2 additions & 0 deletions tests/end-to-end/mock-objects/generator/397.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ $generator = new \PHPUnit\Framework\MockObject\Generator\Generator;
$mock = $generator->generate(
C::class,
true,
true,
[],
'MockC',
true,
Expand All @@ -30,6 +31,7 @@ class MockC extends C implements PHPUnit\Framework\MockObject\MockObjectInternal
{
use PHPUnit\Framework\MockObject\StubApi;
use PHPUnit\Framework\MockObject\MockObjectApi;
use PHPUnit\Framework\MockObject\GeneratedAsMockObject;
use PHPUnit\Framework\MockObject\Method;
use PHPUnit\Framework\MockObject\DoubledCloneMethod;

Expand Down
3 changes: 2 additions & 1 deletion tests/end-to-end/mock-objects/generator/4139.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ require_once __DIR__ . '/../../../bootstrap.php';

$generator = new \PHPUnit\Framework\MockObject\Generator\Generator;

$mock = $generator->generate(InterfaceWithConstructor::class, true);
$mock = $generator->generate(InterfaceWithConstructor::class, true, true);

print $mock->classCode();
--EXPECTF--
Expand All @@ -20,6 +20,7 @@ class %s implements PHPUnit\Framework\MockObject\MockObjectInternal, InterfaceWi
{
use PHPUnit\Framework\MockObject\StubApi;
use PHPUnit\Framework\MockObject\MockObjectApi;
use PHPUnit\Framework\MockObject\GeneratedAsMockObject;
use PHPUnit\Framework\MockObject\Method;
use PHPUnit\Framework\MockObject\DoubledCloneMethod;

Expand Down
2 changes: 2 additions & 0 deletions tests/end-to-end/mock-objects/generator/abstract_class.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ $generator = new \PHPUnit\Framework\MockObject\Generator\Generator;
$mock = $generator->generate(
'Foo',
true,
true,
[],
'MockFoo',
true,
Expand All @@ -34,6 +35,7 @@ class MockFoo extends Foo implements PHPUnit\Framework\MockObject\MockObjectInte
{
use PHPUnit\Framework\MockObject\StubApi;
use PHPUnit\Framework\MockObject\MockObjectApi;
use PHPUnit\Framework\MockObject\GeneratedAsMockObject;
use PHPUnit\Framework\MockObject\Method;
use PHPUnit\Framework\MockObject\DoubledCloneMethod;

Expand Down
2 changes: 2 additions & 0 deletions tests/end-to-end/mock-objects/generator/class.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ $generator = new \PHPUnit\Framework\MockObject\Generator\Generator;
$mock = $generator->generate(
'Foo',
true,
true,
[],
'MockFoo',
true,
Expand All @@ -34,6 +35,7 @@ class MockFoo extends Foo implements PHPUnit\Framework\MockObject\MockObjectInte
{
use PHPUnit\Framework\MockObject\StubApi;
use PHPUnit\Framework\MockObject\MockObjectApi;
use PHPUnit\Framework\MockObject\GeneratedAsMockObject;
use PHPUnit\Framework\MockObject\Method;
use PHPUnit\Framework\MockObject\DoubledCloneMethod;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ $generator = new \PHPUnit\Framework\MockObject\Generator\Generator;
$mock = $generator->generate(
'Foo',
true,
true,
[],
'MockFoo',
true
Expand All @@ -29,6 +30,7 @@ class MockFoo extends Foo implements PHPUnit\Framework\MockObject\MockObjectInte
{
use PHPUnit\Framework\MockObject\StubApi;
use PHPUnit\Framework\MockObject\MockObjectApi;
use PHPUnit\Framework\MockObject\GeneratedAsMockObject;
use PHPUnit\Framework\MockObject\Method;
use PHPUnit\Framework\MockObject\ProxiedCloneMethod;
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ $generator = new \PHPUnit\Framework\MockObject\Generator\Generator;
$mock = $generator->generate(
'Foo',
true,
true,
[],
'MockFoo',
true
Expand All @@ -29,6 +30,7 @@ class MockFoo extends Foo implements PHPUnit\Framework\MockObject\MockObjectInte
{
use PHPUnit\Framework\MockObject\StubApi;
use PHPUnit\Framework\MockObject\MockObjectApi;
use PHPUnit\Framework\MockObject\GeneratedAsMockObject;
use PHPUnit\Framework\MockObject\Method;
use PHPUnit\Framework\MockObject\DoubledCloneMethod;
}
Loading

0 comments on commit db9ae30

Please sign in to comment.