function MethodProphecy::__construct
@internal
Parameters
ObjectProphecy<object> $objectProphecy:
string $methodName:
Argument\ArgumentsWildcard|array<mixed> $arguments:
Throws
\Prophecy\Exception\Doubler\MethodNotFoundException If method not found
File
-
vendor/
phpspec/ prophecy/ src/ Prophecy/ Prophecy/ MethodProphecy.php, line 68
Class
- MethodProphecy
- Method prophecy.
Namespace
Prophecy\ProphecyCode
public function __construct(ObjectProphecy $objectProphecy, $methodName, $arguments) {
$double = $objectProphecy->reveal();
if (!method_exists($double, $methodName)) {
throw new MethodNotFoundException(sprintf('Method `%s::%s()` is not defined.', get_class($double), $methodName), get_class($double), $methodName, $arguments);
}
$this->objectProphecy = $objectProphecy;
$this->methodName = $methodName;
$reflectedMethod = new \ReflectionMethod($double, $methodName);
if ($reflectedMethod->isFinal()) {
throw new MethodProphecyException(sprintf("Can not add prophecy for a method `%s::%s()`\n" . "as it is a final method.", get_class($double), $methodName), $this);
}
$this->withArguments($arguments);
$hasTentativeReturnType = method_exists($reflectedMethod, 'hasTentativeReturnType') && $reflectedMethod->hasTentativeReturnType();
if (true === $reflectedMethod->hasReturnType() || $hasTentativeReturnType) {
if ($hasTentativeReturnType) {
$reflectionType = $reflectedMethod->getTentativeReturnType();
}
else {
$reflectionType = $reflectedMethod->getReturnType();
}
if ($reflectionType instanceof ReflectionNamedType) {
$types = [
$reflectionType,
];
}
elseif ($reflectionType instanceof ReflectionUnionType) {
$types = $reflectionType->getTypes();
}
else {
throw new MethodProphecyException(sprintf("Can not add prophecy for a method `%s::%s()`\nas its return type is not supported by Prophecy yet.", get_class($double), $methodName), $this);
}
$types = array_map(function (ReflectionNamedType $type) {
return $type->getName();
}, $types);
usort($types, static function (string $type1, string $type2) {
// null is lowest priority
if ($type2 == 'null') {
return -1;
}
elseif ($type1 == 'null') {
return 1;
}
// objects are higher priority than scalars
$isObject = static function ($type) {
return class_exists($type) || interface_exists($type);
};
if ($isObject($type1) && !$isObject($type2)) {
return -1;
}
elseif (!$isObject($type1) && $isObject($type2)) {
return 1;
}
// don't sort both-scalars or both-objects
return 0;
});
$defaultType = $types[0];
if ('void' === $defaultType) {
$this->voidReturnType = true;
}
$this->will(function ($args, ObjectProphecy $object, MethodProphecy $method) use ($defaultType) {
switch ($defaultType) {
case 'void':
return;
case 'string':
return '';
case 'float':
return 0.0;
case 'int':
return 0;
case 'bool':
return false;
case 'array':
return array();
case 'true':
return true;
case 'false':
return false;
case 'null':
return null;
case 'callable':
case 'Closure':
return function () {
};
case 'Traversable':
case 'Generator':
return (function () {
yield;
})();
case 'object':
$prophet = new Prophet();
return $prophet->prophesize()
->reveal();
default:
if (!class_exists($defaultType) && !interface_exists($defaultType)) {
throw new MethodProphecyException(sprintf('Cannot create a return value for the method as the type "%s" is not supported. Configure an explicit return value instead.', $defaultType), $method);
}
$prophet = new Prophet();
return $prophet->prophesize($defaultType)
->reveal();
}
});
}
}