Ho implementato approccio @Vadym ed aggiornato esso. Ora lo uso per testare con successo!
protected function getFinalMock($originalObject)
{
if (gettype($originalObject) !== 'object') {
throw new \Exception('Argument must be an object');
}
$allOriginalMethods = get_class_methods($originalObject);
// some "unmockable" methods will be skipped
$skipMethods = [
'__construct',
'staticProxyConstructor',
'__get',
'__set',
'__isset',
'__unset',
'__clone',
'__sleep',
'__wakeup',
'setProxyInitializer',
'getProxyInitializer',
'initializeProxy',
'isProxyInitialized',
'getWrappedValueHolderValue',
'create',
];
// list of all methods of Query object
$originalMethods = [];
foreach ($allOriginalMethods as $method) {
if (!in_array($method, $skipMethods)) {
$originalMethods[] = $method;
}
}
$reflection = new \ReflectionClass($originalObject);
$parentClass = $reflection->getParentClass()->name;
// Very dummy mock
$mock = $this
->getMockBuilder($parentClass)
->disableOriginalConstructor()
->setMethods($originalMethods)
->getMock();
foreach ($originalMethods as $method) {
// skip "unmockable"
if (in_array($method, $skipMethods)) {
continue;
}
// make proxy call to rest of the methods
$mock
->expects($this->any())
->method($method)
->will($this->returnCallback(
function (...$args) use ($originalObject, $method, $mock) {
$ret = call_user_func_array([$originalObject, $method], $args);
// mocking "return $this;" from inside $originalQuery
if (is_object($ret) && get_class($ret) == get_class($originalObject)) {
if (spl_object_hash($originalObject) == spl_object_hash($ret)) {
return $mock;
}
throw new \Exception(
sprintf(
'Object [%s] of class [%s] returned clone of itself from method [%s]. Not supported.',
spl_object_hash($originalObject),
get_class($originalObject),
$method
)
);
}
return $ret;
}
));
}
return $mock;
}
è possibile creare una copia della classe finale che non è definitivo e mock –
@BryantFrankford grazie per la soluzione . Mentre ciò funzionerebbe, preferirei idealmente evitare di scrivere una nuova classe per questa specifica situazione. Non ti accorgerai di una soluzione che si ridimensionerà un po 'meglio? Se questo diventa il mio progetto allora implementerò la soluzione di cui sopra – DanHabib
Oltre a cambiare la classe originale per non essere definitiva, personalmente non ho altra soluzione. –