TYPO3 CMS  TYPO3_7-6
BaseTestCase.php
Go to the documentation of this file.
1 <?php
2 namespace TYPO3\CMS\Core\Tests;
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
18 
26 abstract class BaseTestCase extends \PHPUnit_Framework_TestCase
27 {
33  protected $backupGlobals = true;
34 
40  protected $backupStaticAttributes = false;
41 
58  protected function getAccessibleMock(
59  $originalClassName, $methods = [], array $arguments = [], $mockClassName = '',
60  $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true
61  ) {
62  if ($originalClassName === '') {
63  throw new \InvalidArgumentException('$originalClassName must not be empty.', 1334701880);
64  }
65 
66  return $this->getMock(
67  $this->buildAccessibleProxy($originalClassName),
68  $methods,
69  $arguments,
70  $mockClassName,
71  $callOriginalConstructor,
72  $callOriginalClone,
73  $callAutoload
74  );
75  }
76 
96  $originalClassName, array $arguments = [], $mockClassName = '',
97  $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true, $mockedMethods = []
98  ) {
99  if ($originalClassName === '') {
100  throw new \InvalidArgumentException('$originalClassName must not be empty.', 1384268260);
101  }
102 
103  return $this->getMockForAbstractClass(
104  $this->buildAccessibleProxy($originalClassName),
105  $arguments,
106  $mockClassName,
107  $callOriginalConstructor,
108  $callOriginalClone,
109  $callAutoload,
110  $mockedMethods
111  );
112  }
113 
121  protected function buildAccessibleProxy($className)
122  {
123  $accessibleClassName = $this->getUniqueId('Tx_Phpunit_AccessibleProxy');
124  $class = new \ReflectionClass($className);
125  $abstractModifier = $class->isAbstract() ? 'abstract ' : '';
126 
127  eval(
128  $abstractModifier . 'class ' . $accessibleClassName .
129  ' extends ' . $className . ' implements ' . \TYPO3\CMS\Core\Tests\AccessibleObjectInterface::class . ' {' .
130  'public function _call($methodName) {' .
131  'if ($methodName === \'\') {' .
132  'throw new \InvalidArgumentException(\'$methodName must not be empty.\', 1334663993);' .
133  '}' .
134  '$args = func_get_args();' .
135  'return call_user_func_array(array($this, $methodName), array_slice($args, 1));' .
136  '}' .
137  'public function _callRef(' .
138  '$methodName, &$arg1 = NULL, &$arg2 = NULL, &$arg3 = NULL, &$arg4 = NULL, &$arg5= NULL, &$arg6 = NULL, ' .
139  '&$arg7 = NULL, &$arg8 = NULL, &$arg9 = NULL' .
140  ') {' .
141  'if ($methodName === \'\') {' .
142  'throw new \InvalidArgumentException(\'$methodName must not be empty.\', 1334664210);' .
143  '}' .
144  'switch (func_num_args()) {' .
145  'case 0:' .
146  'throw new RuntimeException(\'The case of 0 arguments is not supposed to happen.\', 1334703124);' .
147  'break;' .
148  'case 1:' .
149  '$returnValue = $this->$methodName();' .
150  'break;' .
151  'case 2:' .
152  '$returnValue = $this->$methodName($arg1);' .
153  'break;' .
154  'case 3:' .
155  '$returnValue = $this->$methodName($arg1, $arg2);' .
156  'break;' .
157  'case 4:' .
158  '$returnValue = $this->$methodName($arg1, $arg2, $arg3);' .
159  'break;' .
160  'case 5:' .
161  '$returnValue = $this->$methodName($arg1, $arg2, $arg3, $arg4);' .
162  'break;' .
163  'case 6:' .
164  '$returnValue = $this->$methodName($arg1, $arg2, $arg3, $arg4, $arg5);' .
165  'break;' .
166  'case 7:' .
167  '$returnValue = $this->$methodName($arg1, $arg2, $arg3, $arg4, $arg5, $arg6);' .
168  'break;' .
169  'case 8:' .
170  '$returnValue = $this->$methodName($arg1, $arg2, $arg3, $arg4, $arg5, $arg6, $arg7);' .
171  'break;' .
172  'case 9:' .
173  '$returnValue = $this->$methodName($arg1, $arg2, $arg3, $arg4, $arg5, $arg6, $arg7, $arg8);' .
174  'break;' .
175  'case 10:' .
176  '$returnValue = $this->$methodName(' .
177  '$arg1, $arg2, $arg3, $arg4, $arg5, $arg6, $arg7, $arg8, $arg9' .
178  ');' .
179  'break;' .
180  'default:' .
181  'throw new \InvalidArgumentException(' .
182  '\'_callRef currently only allows calls to methods with no more than 9 parameters.\'' .
183  ');' .
184  '}' .
185  'return $returnValue;' .
186  '}' .
187  'public function _set($propertyName, $value) {' .
188  'if ($propertyName === \'\') {' .
189  'throw new \InvalidArgumentException(\'$propertyName must not be empty.\', 1334664355);' .
190  '}' .
191  '$this->$propertyName = $value;' .
192  '}' .
193  'public function _setRef($propertyName, &$value) {' .
194  'if ($propertyName === \'\') {' .
195  'throw new \InvalidArgumentException(\'$propertyName must not be empty.\', 1334664545);' .
196  '}' .
197  '$this->$propertyName = $value;' .
198  '}' .
199  'public function _setStatic($propertyName, $value) {' .
200  'if ($propertyName === \'\') {' .
201  'throw new \InvalidArgumentException(\'$propertyName must not be empty.\', 1344242602);' .
202  '}' .
203  'self::$$propertyName = $value;' .
204  '}' .
205  'public function _get($propertyName) {' .
206  'if ($propertyName === \'\') {' .
207  'throw new \InvalidArgumentException(\'$propertyName must not be empty.\', 1334664967);' .
208  '}' .
209  'return $this->$propertyName;' .
210  '}' .
211  'public function _getStatic($propertyName) {' .
212  'if ($propertyName === \'\') {' .
213  'throw new \InvalidArgumentException(\'$propertyName must not be empty.\', 1344242603);' .
214  '}' .
215  'return self::$$propertyName;' .
216  '}' .
217  '}'
218  );
219 
220  return $accessibleClassName;
221  }
222 
230  protected function callInaccessibleMethod($object, $name)
231  {
232  // Remove first two arguments ($object and $name)
233  $arguments = func_get_args();
234  array_splice($arguments, 0, 2);
235 
236  $reflectionObject = new \ReflectionObject($object);
237  $reflectionMethod = $reflectionObject->getMethod($name);
238  $reflectionMethod->setAccessible(true);
239  return $reflectionMethod->invokeArgs($object, $arguments);
240  }
241 
255  protected function inject($target, $name, $dependency)
256  {
257  if (!is_object($target)) {
258  throw new \InvalidArgumentException('Wrong type for argument $target, must be object.');
259  }
260 
261  $objectReflection = new \ReflectionObject($target);
262  $methodNamePart = strtoupper($name[0]) . substr($name, 1);
263  if ($objectReflection->hasMethod('set' . $methodNamePart)) {
264  $methodName = 'set' . $methodNamePart;
265  $target->$methodName($dependency);
266  } elseif ($objectReflection->hasMethod('inject' . $methodNamePart)) {
267  $methodName = 'inject' . $methodNamePart;
268  $target->$methodName($dependency);
269  } elseif ($objectReflection->hasProperty($name)) {
270  $property = $objectReflection->getProperty($name);
271  $property->setAccessible(true);
272  $property->setValue($target, $dependency);
273  } else {
274  throw new \RuntimeException('Could not inject ' . $name . ' into object of type ' . get_class($target));
275  }
276  }
277 
287  protected function getUniqueId($prefix = '')
288  {
289  return $prefix . StringUtility::getUniqueId(mt_rand());
290  }
291 }
inject($target, $name, $dependency)
getAccessibleMockForAbstractClass( $originalClassName, array $arguments=[], $mockClassName='', $callOriginalConstructor=true, $callOriginalClone=true, $callAutoload=true, $mockedMethods=[])
getAccessibleMock( $originalClassName, $methods=[], array $arguments=[], $mockClassName='', $callOriginalConstructor=true, $callOriginalClone=true, $callAutoload=true)