Skip to content

Commit

Permalink
Closes #5048
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastianbergmann committed Oct 20, 2023
1 parent f8601ff commit 42e0c55
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 0 deletions.
7 changes: 7 additions & 0 deletions ChangeLog-10.4.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

All notable changes of the PHPUnit 10.4 release series are documented in this file using the [Keep a CHANGELOG](https://keepachangelog.com/) principles.

## [10.4.2] - 2023-MM-DD

### Fixed

* [#5048](https://github.com/sebastianbergmann/phpunit/issues/5048): Methods that return `never` cannot be doubled

## [10.4.1] - 2023-10-08

### Fixed
Expand Down Expand Up @@ -41,5 +47,6 @@ All notable changes of the PHPUnit 10.4 release series are documented in this fi
* `PHPUnit\TextUI\Configuration\Configuration::cliArgument()` and `PHPUnit\TextUI\Configuration\Configuration::hasCliArgument()`
* `PHPUnit\Framework\Constraint\Constraint::exporter()`

[10.4.2]: https://github.com/sebastianbergmann/phpunit/compare/10.4.1...10.4
[10.4.1]: https://github.com/sebastianbergmann/phpunit/compare/10.4.0...10.4.1
[10.4.0]: https://github.com/sebastianbergmann/phpunit/compare/10.3.5...10.4.0
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php declare(strict_types=1);
/*
* This file is part of PHPUnit.
*
* (c) Sebastian Bergmann <sebastian@phpunit.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace PHPUnit\Framework\MockObject;

use function sprintf;
use RuntimeException;

/**
* @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
*/
final class NeverReturningMethodException extends RuntimeException implements Exception
{
/**
* @psalm-param class-string $className
* @psalm-param non-empty-string $methodName
*/
public function __construct(string $className, string $methodName)
{
parent::__construct(
sprintf(
'Method %s::%s() is declared to never return',
$className,
$methodName,
),
);
}
}
7 changes: 7 additions & 0 deletions src/Framework/MockObject/Runtime/Invocation.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,13 @@ public function parameters(): array
*/
public function generateReturnValue(): mixed
{
if ($this->returnType === 'never') {
throw new NeverReturningMethodException(
$this->className,
$this->methodName,
);
}

if ($this->isReturnTypeNullable || $this->proxiedCall) {
return null;
}
Expand Down
15 changes: 15 additions & 0 deletions tests/_files/mock-object/InterfaceWithNeverReturningMethod.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php declare(strict_types=1);
/*
* This file is part of PHPUnit.
*
* (c) Sebastian Bergmann <sebastian@phpunit.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace PHPUnit\TestFixture\MockObject;

interface InterfaceWithNeverReturningMethod
{
public function m(): never;
}
11 changes: 11 additions & 0 deletions tests/unit/Framework/MockObject/TestDoubleTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use PHPUnit\Framework\TestCase;
use PHPUnit\TestFixture\MockObject\ExtendableClassWithCloneMethod;
use PHPUnit\TestFixture\MockObject\InterfaceWithMethodThatExpectsObject;
use PHPUnit\TestFixture\MockObject\InterfaceWithNeverReturningMethod;
use PHPUnit\TestFixture\MockObject\InterfaceWithReturnTypeDeclaration;
use stdClass;

Expand Down Expand Up @@ -222,6 +223,16 @@ public function testOriginalCloneMethodCanOptionallyBeCalledWhenTestDoubleObject
clone $double;
}

public function testThrowsExceptionWhenMethodWithNeverReturnTypeDeclarationIsCalled(): void
{
$double = $this->createTestDouble(InterfaceWithNeverReturningMethod::class);

$this->expectException(NeverReturningMethodException::class);
$this->expectExceptionMessage('Method PHPUnit\TestFixture\MockObject\InterfaceWithNeverReturningMethod::m() is declared to never return');

$double->m();
}

/**
* @psalm-template RealInstanceType of object
*
Expand Down

0 comments on commit 42e0c55

Please sign in to comment.