makeEmpty/make silently loses property values for PHP 8.4+ hooked properties
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 68/100
Direzione di ricerca
Inizia in Stub.php, intorno alle righe 523–526, dove Stub::bindParameters() passa alla reflection del parent per gli oggetti mock di PHPUnit, e riproduci il problema con una proprietà hooked in PHP 8.4+. Verifica come PHPUnit 13 espone le proprietà hooked tramite '$prop::get' e determina come dovrebbero essere rilevate le proprietà hooked. Il lavoro è completato quando i valori passati a makeEmpty() e make() rimangono leggibili, inclusi i valori i cui tipi di proprietà sono classi finali.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Environment
- PHP: 8.5.6 (reproduces on PHP 8.4+, the version that introduced property hooks)
- codeception/stub: 4.3.0
- phpunit/phpunit: 13.0.6
Problem
When mocking a class that has PHP 8.4 property hooks, values passed to makeEmpty() / make() for hooked properties are silently lost. Depending on the property type, this either returns null / an auto-generated stub, or throws a RuntimeException if the property type is a final class.
A real-world trigger: symfony/http-foundation 8.1 added set hooks with deprecation warnings to all major public bags on Request ($request, $query, $attributes, etc.), causing all tests that mock Request with those properties to break.
Minimal reproduction
class Foo
{
public string $bar {
set { $this->bar = $value; }
}
}
// Value is silently lost
$mock = $this->makeEmpty(Foo::class, ['bar' => 'baz']);
var_dump($mock->bar); // expected: string(3) baz, actual: auto-stub or error
With a final-typed property (e.g. InputBag):
// Throws RuntimeException:
// Return value for MockObject_Request::::get() cannot be generated:
// Class "Symfony\Component\HttpFoundation\InputBag" is declared "final"
$mock = $this->makeEmpty(Request::class, ['request' => new InputBag(['foo' => 'bar'])]);
$mock->request->get('foo'); // boom
Root cause
Stub::bindParameters() deliberately switches to getParentClass() for PHPUnit mock objects (line 523–526 in Stub.php), then calls ReflectionProperty::setValue() on the parent's reflection:
if ($mock instanceof PHPUnitMockObject) {
$reflectionClass = $reflectionClass->getParentClass(); // Request::class
}
// ...
$reflectionProperty->setValue($mock, $value); // writes to parent's backing store
In PHP 8.4, a class that redeclares a property with hooks (as PHPUnit's mock generator does when the source class has hooks — see phpunit#6549) gets its own separate backing store. The write goes into the parent's backing store; the read goes through the mock's generated get hook, which reads from the mock's backing store — they never meet.
Possible fix direction
For properties that have hooks in the source class, bindParameters() should configure the mock via PHPUnit's mock API instead of ReflectionProperty::setValue():
// PHPUnit 13 exposes hooked properties as mockable methods named '$prop::get'
$mock->method('$bar::get')->willReturn('baz');
This requires detecting hooked properties (via ReflectionProperty::hasHooks() / getHook(), available since PHP 8.4) and branching accordingly.
- Lingua principale
- PHP
- Stelle
- 301
- Fork
- 19
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Guida per i contributori
Nessuna guida per i contributori indicizzata per questo repository
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di Codeception/Stub
-
Difficoltà 3/5 1-2 giorni Idoneità per principianti 42/100
Codeception/Stub#45 · 1 commento ·
-
Difficoltà 3/5 1-2 giorni Idoneità per principianti 35/100
Codeception/Stub#36 ·
-
Difficoltà 3/5 1-2 giorni Idoneità per principianti 35/100
Codeception/Stub#30 · 1 reazione ·
-
Difficoltà 3/5 1-2 giorni Idoneità per principianti 48/100
Codeception/Stub#7 · 5 reazioni ·
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 48/100
Codeception/Stub#31 · 3 commenti ·
Tutte le issue di Codeception/Stub
Issue simili
-
[Chore] Keep one viget-block-generator skill and replicate it, instead of four tracked copies Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 85/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
hector-jewell/food-delivery-system-for-restaurant-using-php#1311 ·
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
Sylius/SyliusGridBundle#501 ·