Tôi đã thực hiện cách tiếp cận @Vadym và cập nhật nó. Bây giờ tôi sử dụng nó để thử nghiệm thành công!
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;
}
Bạn có thể tạo một bản sao của lớp CUỐI CÙNG đó không phải là CUỐI CÙNG và chế nhạo nó –
@BryantFrankford nhờ cho các giải pháp . Trong khi điều này sẽ làm việc, lý tưởng nhất là tôi muốn tránh viết một lớp mới cho tình huống cụ thể này. Bạn sẽ không xảy ra để nhận thức được một giải pháp mà sẽ quy mô tốt hơn một chút? Nếu điều này trở nên gating cho dự án của tôi sau đó tôi sẽ thực hiện các giải pháp trên – DanHabib
Khác với việc thay đổi lớp gốc để không được cuối cùng, cá nhân tôi không có bất kỳ giải pháp khác. –