TYPO3CMS  8
 All Classes Namespaces Files Functions Variables Pages
Classes/Tests/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  $mockBuilder = $this->getMockBuilder($this->buildAccessibleProxy($originalClassName))
67  ->setMethods($methods)
68  ->setConstructorArgs($arguments)
69  ->setMockClassName($mockClassName);
70 
71  if (!$callOriginalConstructor) {
72  $mockBuilder->disableOriginalConstructor();
73  }
74 
75  if (!$callOriginalClone) {
76  $mockBuilder->disableOriginalClone();
77  }
78 
79  if (!$callAutoload) {
80  $mockBuilder->disableAutoload();
81  }
82 
83  return $mockBuilder->getMock();
84  }
85 
105  $originalClassName, array $arguments = [], $mockClassName = '',
106  $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true, $mockedMethods = []
107  ) {
108  if ($originalClassName === '') {
109  throw new \InvalidArgumentException('$originalClassName must not be empty.', 1384268260);
110  }
111 
112  return $this->getMockForAbstractClass(
113  $this->buildAccessibleProxy($originalClassName),
114  $arguments,
115  $mockClassName,
116  $callOriginalConstructor,
117  $callOriginalClone,
118  $callAutoload,
119  $mockedMethods
120  );
121  }
122 
130  protected function buildAccessibleProxy($className)
131  {
132  $accessibleClassName = $this->getUniqueId('Tx_Phpunit_AccessibleProxy');
133  $class = new \ReflectionClass($className);
134  $abstractModifier = $class->isAbstract() ? 'abstract ' : '';
135 
136  eval(
137  $abstractModifier . 'class ' . $accessibleClassName .
138  ' extends ' . $className . ' implements ' . \TYPO3\CMS\Core\Tests\AccessibleObjectInterface::class . ' {' .
139  'public function _call($methodName) {' .
140  'if ($methodName === \'\') {' .
141  'throw new \InvalidArgumentException(\'$methodName must not be empty.\', 1334663993);' .
142  '}' .
143  '$args = func_get_args();' .
144  'return call_user_func_array(array($this, $methodName), array_slice($args, 1));' .
145  '}' .
146  'public function _callRef(' .
147  '$methodName, &$arg1 = NULL, &$arg2 = NULL, &$arg3 = NULL, &$arg4 = NULL, &$arg5= NULL, &$arg6 = NULL, ' .
148  '&$arg7 = NULL, &$arg8 = NULL, &$arg9 = NULL' .
149  ') {' .
150  'if ($methodName === \'\') {' .
151  'throw new \InvalidArgumentException(\'$methodName must not be empty.\', 1334664210);' .
152  '}' .
153  'switch (func_num_args()) {' .
154  'case 0:' .
155  'throw new RuntimeException(\'The case of 0 arguments is not supposed to happen.\', 1334703124);' .
156  'break;' .
157  'case 1:' .
158  '$returnValue = $this->$methodName();' .
159  'break;' .
160  'case 2:' .
161  '$returnValue = $this->$methodName($arg1);' .
162  'break;' .
163  'case 3:' .
164  '$returnValue = $this->$methodName($arg1, $arg2);' .
165  'break;' .
166  'case 4:' .
167  '$returnValue = $this->$methodName($arg1, $arg2, $arg3);' .
168  'break;' .
169  'case 5:' .
170  '$returnValue = $this->$methodName($arg1, $arg2, $arg3, $arg4);' .
171  'break;' .
172  'case 6:' .
173  '$returnValue = $this->$methodName($arg1, $arg2, $arg3, $arg4, $arg5);' .
174  'break;' .
175  'case 7:' .
176  '$returnValue = $this->$methodName($arg1, $arg2, $arg3, $arg4, $arg5, $arg6);' .
177  'break;' .
178  'case 8:' .
179  '$returnValue = $this->$methodName($arg1, $arg2, $arg3, $arg4, $arg5, $arg6, $arg7);' .
180  'break;' .
181  'case 9:' .
182  '$returnValue = $this->$methodName($arg1, $arg2, $arg3, $arg4, $arg5, $arg6, $arg7, $arg8);' .
183  'break;' .
184  'case 10:' .
185  '$returnValue = $this->$methodName(' .
186  '$arg1, $arg2, $arg3, $arg4, $arg5, $arg6, $arg7, $arg8, $arg9' .
187  ');' .
188  'break;' .
189  'default:' .
190  'throw new \InvalidArgumentException(' .
191  '\'_callRef currently only allows calls to methods with no more than 9 parameters.\', 1476049901' .
192  ');' .
193  '}' .
194  'return $returnValue;' .
195  '}' .
196  'public function _set($propertyName, $value) {' .
197  'if ($propertyName === \'\') {' .
198  'throw new \InvalidArgumentException(\'$propertyName must not be empty.\', 1334664355);' .
199  '}' .
200  '$this->$propertyName = $value;' .
201  '}' .
202  'public function _setRef($propertyName, &$value) {' .
203  'if ($propertyName === \'\') {' .
204  'throw new \InvalidArgumentException(\'$propertyName must not be empty.\', 1334664545);' .
205  '}' .
206  '$this->$propertyName = $value;' .
207  '}' .
208  'public function _setStatic($propertyName, $value) {' .
209  'if ($propertyName === \'\') {' .
210  'throw new \InvalidArgumentException(\'$propertyName must not be empty.\', 1344242602);' .
211  '}' .
212  'self::$$propertyName = $value;' .
213  '}' .
214  'public function _get($propertyName) {' .
215  'if ($propertyName === \'\') {' .
216  'throw new \InvalidArgumentException(\'$propertyName must not be empty.\', 1334664967);' .
217  '}' .
218  'return $this->$propertyName;' .
219  '}' .
220  'public function _getStatic($propertyName) {' .
221  'if ($propertyName === \'\') {' .
222  'throw new \InvalidArgumentException(\'$propertyName must not be empty.\', 1344242603);' .
223  '}' .
224  'return self::$$propertyName;' .
225  '}' .
226  '}'
227  );
228 
229  return $accessibleClassName;
230  }
231 
240  protected function callInaccessibleMethod($object, $name, ...$arguments)
241  {
242  $reflectionObject = new \ReflectionObject($object);
243  $reflectionMethod = $reflectionObject->getMethod($name);
244  $reflectionMethod->setAccessible(true);
245  return $reflectionMethod->invokeArgs($object, $arguments);
246  }
247 
261  protected function inject($target, $name, $dependency)
262  {
263  if (!is_object($target)) {
264  throw new \InvalidArgumentException('Wrong type for argument $target, must be object.', 1476107338);
265  }
266 
267  $objectReflection = new \ReflectionObject($target);
268  $methodNamePart = strtoupper($name[0]) . substr($name, 1);
269  if ($objectReflection->hasMethod('set' . $methodNamePart)) {
270  $methodName = 'set' . $methodNamePart;
271  $target->$methodName($dependency);
272  } elseif ($objectReflection->hasMethod('inject' . $methodNamePart)) {
273  $methodName = 'inject' . $methodNamePart;
274  $target->$methodName($dependency);
275  } elseif ($objectReflection->hasProperty($name)) {
276  $property = $objectReflection->getProperty($name);
277  $property->setAccessible(true);
278  $property->setValue($target, $dependency);
279  } else {
280  throw new \RuntimeException(
281  'Could not inject ' . $name . ' into object of type ' . get_class($target),
282  1476107339
283  );
284  }
285  }
286 
296  protected function getUniqueId($prefix = '')
297  {
298  return $prefix . StringUtility::getUniqueId(mt_rand());
299  }
300 }
callInaccessibleMethod($object, $name,...$arguments)
getAccessibleMockForAbstractClass($originalClassName, array $arguments=[], $mockClassName= '', $callOriginalConstructor=true, $callOriginalClone=true, $callAutoload=true, $mockedMethods=[])
getAccessibleMock($originalClassName, $methods=[], array $arguments=[], $mockClassName= '', $callOriginalConstructor=true, $callOriginalClone=true, $callAutoload=true)