public final function generateCode(ReflectionClass $class, $test_double_class_name, array $interfaces = array(), array $traits = array(), $method_checker = null) { FBMock_Utils::assertString($test_double_class_name); if ($class->isFinal() && !$this->canOverrideFinals()) { throw new FBMock_TestDoubleException("Cannot mock final class %s", $class->getName()); } $code = $this->getMockClassHeader($class, $test_double_class_name, $interfaces, $traits) . "\n"; $method_sources = array(); foreach ($class->getMethods() as $method) { $method_checker && $method_checker($class, $method); if ($method->isFinal() && !$this->canOverrideFinals()) { continue; } // #1137433 if (!$class->isInterface()) { $method = new ReflectionMethod($class->getName(), $method->getName()); } $test_double_method_generator = FBMock_Config::get()->getMethodGenerator(); $method_source = $test_double_method_generator->generateCode($method); if ($method_source) { $method_sources[] = $method_source; } } $code .= implode("\n\n", $method_sources); $code .= "\n}"; // close class return $code; }
/** * Create a strict mock object of type $class_name. * * "Strict" means that if any unmocked method is called, an exception will be * thrown. */ function strict_mock($class_name) { FBMock_Utils::assertString($class_name); $interface_names = func_get_args(); array_shift($interface_names); return FBMock_Config::get()->getMockCreator()->createStrictMock($class_name, $interface_names); }
public final function createMock($class_name, $extra_interfaces = array()) { FBMock_Utils::assertString($class_name); list($interface_names, $trait_names) = FBMock_Utils::getInterfacesAndTraits($extra_interfaces); $double = FBMock_Config::get()->getTestDoubleCreator()->createTestDoubleFor($class_name, $interface_names, $trait_names, function (ReflectionClass $class, ReflectionMethod $method) { if (strpos($method->getName(), 'mock') === 0) { throw new FBMock_MockObjectException('%s cannot be mocked because it has a method name that starts ' . 'with "mock": %s. Methods named mock____ are reserved for ' . 'configuring mock objects.', $class->getName(), $method->getName()); } }); FBMock_Utils::setDoubleImplementation($double, FBMock_Config::get()->createMockImplementation($class_name)); $this->postCreateHandler($double); return $double; }
public final function createTestDoubleFor($class_name, array $interfaces = array(), array $traits = array(), $method_checker = null) { FBMock_Utils::assertString($class_name); $this->assertAllowed(); if (!class_exists($class_name) && !interface_exists($class_name)) { throw new FBMock_TestDoubleException("Attempting to mock {$class_name} but {$class_name} isn't loaded."); } $mock_class_name = FBMock_Utils::mockClassNameFor($class_name, $interfaces, $traits); $ref_class = new ReflectionClass($class_name); if ($ref_class->isInternal() && !FBMock_Utils::isHHVM()) { throw new FBMock_TestDoubleException("Trying to mock PHP internal class {$class_name}. Mocking of internal " . "classes is only supported in HHVM."); } if (!class_exists($mock_class_name, $autoload = false)) { $class_generator_class = FBMock_Config::get()->getClassGenerator(); $class_generator = new $class_generator_class(); $code = $class_generator->generateCode($ref_class, $mock_class_name, $interfaces, $traits, $method_checker); eval($code); } $mock_object = (new ReflectionClass($mock_class_name))->newInstanceWithoutConstructor(); return $mock_object; }
public static function getInterfacesAndTraits(array $interfaces = array()) { $interfaces[] = 'FBMock_Mock'; return array($interfaces, FBMock_Config::get()->getMockTraits()); }