/** * Creates a mock from the target class * * @param string $class * @param array $args * @param array $spec * * @return \PHPUnit_Framework_MockObject_MockObject */ private function _setupTarget_setupMock($class, $args, $spec) { /* * $spec = ['method', 'method', ...] * $spec = [ * 'method' => int, * 'method' => [ 'count' => int, 'with' => mixed, 'return' => mixed ] * ], * */ if (is_string($spec)) { $mock = $this->{$spec}(); } else { $call = function ($spec) { $cb = [$this, $spec[0]]; $args = isset($spec[1]) ? (array) $spec[1] : false; if ($args) { return call_user_func_array($cb, $args); } return $this->{$cb}(); }; $methods = []; $methodMocks = []; foreach ($spec as $method => $methodSpec) { if (is_int($method)) { $methods[] = $methodSpec; continue; } if (is_string($methodSpec)) { $methodSpec = $this->{$methodSpec}(); } $methods[] = $method; $methodMocks[$method] = ['expects' => isset($methodSpec['count']) ? $this->exactly($methodSpec['count']) : $this->any(), 'with' => isset($methodSpec['@with']) ? $call($methodSpec['@with']) : (isset($methodSpec['with']) ? $methodSpec['with'] : null), 'return' => isset($methodSpec['@return']) ? $call($methodSpec['@return']) : (isset($methodSpec['return']) ? '__self__' == $methodSpec['return'] ? $this->returnSelf() : $this->returnValue($methodSpec['return']) : null)]; } $mockBuilder = $this->getMockBuilder($class)->setMethods($methods); if (false === $args) { $mockBuilder->disableOriginalConstructor(); } else { $mockBuilder->setConstructorArgs(InstanceCreator::mapArray($args)); } $mock = $mockBuilder->getMock(); foreach ($methodMocks as $method => $mockSpec) { $methodMock = $mock->expects($mockSpec['expects'])->method($method); if ($mockSpec['with']) { $methodMock->with($mockSpec['with']); } if ($mockSpec['return']) { $methodMock->will($mockSpec['return']); } } } return $mock; }
/** * @testdox Allows setting and/or getting object property values. * @dataProvider propertiesProvider */ public function testSetterAndGetter($name, $spec) { $errTmpl = __METHOD__ . ': ' . get_class($this); if (!property_exists($this, 'target') || !is_object($this->target) && !isset($spec['target'])) { throw new \PHPUnit_Framework_Exception($errTmpl . ' must define the property "target" and the value must be an object.'); } if (!is_array($spec)) { $spec = ['value' => $spec]; } if (isset($spec['@value'])) { $spec['value'] = InstanceCreator::fromSpec($spec['@value'], InstanceCreator::FORCE_INSTANTIATION); } /* Value could be 'null', so we need to use array_key_exists here. */ if (!array_key_exists('value', $spec)) { if (!array_key_exists('default', $spec)) { throw new \PHPUnit_Framework_Exception($errTmpl . ': Specification must contain the key "value" or "default".'); } $spec['value'] = null; $spec['ignore_getter'] = true; $spec['ignore_setter'] = true; } if (isset($spec['target'])) { $this->target = is_object($spec['target']) ? $spec['target'] : InstanceCreator::fromSpec($spec['target'], InstanceCreator::FORCE_INSTANTIATION); } if (isset($spec['@default'])) { $spec['default'] = InstanceCreator::fromSpec($spec['@default'], InstanceCreator::FORCE_INSTANTIATION); } else { if (isset($spec['default@'])) { $spec['default'] = '@' . $spec['default@']; } } if (is_string($spec['value']) && 0 === strpos($spec['value'], '@')) { $spec['value'] = InstanceCreator::newClass($spec['value']); } $this->_setterGetter_triggerHook('pre', $spec); $getterMethod = isset($spec['getter_method']) ? str_replace('*', $name, $spec['getter_method']) : "get{$name}"; $setterMethod = isset($spec['setter_method']) ? str_replace('*', $name, $spec['setter_method']) : "set{$name}"; $getterArgs = isset($spec['getter_args']) ? $spec['getter_args'] : false; $setterArgs = isset($spec['setter_args']) ? $spec['setter_args'] : false; if (isset($spec['setter_exception'])) { $this->_setterGetter_assertSetterGetterException($setterMethod, $spec['setter_exception'], $spec['value'], $setterArgs); return; } if (isset($spec['default'])) { $defaultGetterArgs = isset($spec['default_args']) ? $spec['default_args'] : $getterArgs; $assert = isset($spec['default_assert']) ? $spec['default_assert'] : null; $this->_setterGetter_assertGetterValue($getterMethod, $spec['default'], $defaultGetterArgs, $assert, true); } if (!isset($spec['ignore_setter']) || !$spec['ignore_setter']) { $assert = isset($spec['setter_assert']) ? $spec['setter_assert'] : null; $this->_setterGetter_assertSetterValue($setterMethod, $spec['value'], $setterArgs, $assert, array_key_exists('setter_value', $spec) ? $spec['setter_value'] : '__FLUENT_INTERFACE__'); } if (isset($spec['getter_exception'])) { $this->_setterGetter_assertSetterGetterException($getterMethod, $spec['getter_exception'], '__GETTER_EXCEPTION__', $getterArgs); return; } if (isset($spec['expect_property'])) { $assert = isset($spec['property_assert']) ? $spec['property_assert'] : null; $this->_setterGetter_assertPropertyValue($name, $spec['expect_property'], $assert); } else { if (!isset($spec['ignore_getter']) || !$spec['ignore_getter']) { $assert = isset($spec['getter_assert']) ? $spec['getter_assert'] : null; $this->_setterGetter_assertGetterValue($getterMethod, isset($spec['expect']) ? $spec['expect'] : $spec['value'], $getterArgs, $assert); } } $this->_setterGetter_triggerHook('post', $spec); }