PhpunitCompatibilityTrait.php 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. <?php
  2. namespace Drupal\Tests;
  3. /**
  4. * Makes Drupal's test API forward compatible with multiple versions of PHPUnit.
  5. */
  6. trait PhpunitCompatibilityTrait {
  7. /**
  8. * Returns a mock object for the specified class using the available method.
  9. *
  10. * The getMock method does not exist in PHPUnit 6. To provide backward
  11. * compatibility this trait provides the getMock method and uses createMock if
  12. * this method is available on the parent class.
  13. *
  14. * @param string $originalClassName
  15. * Name of the class to mock.
  16. * @param array|null $methods
  17. * When provided, only methods whose names are in the array are replaced
  18. * with a configurable test double. The behavior of the other methods is not
  19. * changed. Providing null means that no methods will be replaced.
  20. * @param array $arguments
  21. * Parameters to pass to the original class' constructor.
  22. * @param string $mockClassName
  23. * Class name for the generated test double class.
  24. * @param bool $callOriginalConstructor
  25. * Can be used to disable the call to the original class' constructor.
  26. * @param bool $callOriginalClone
  27. * Can be used to disable the call to the original class' clone constructor.
  28. * @param bool $callAutoload
  29. * Can be used to disable __autoload() during the generation of the test
  30. * double class.
  31. * @param bool $cloneArguments
  32. * Enables the cloning of arguments passed to mocked methods.
  33. * @param bool $callOriginalMethods
  34. * Enables the invocation of the original methods.
  35. * @param object $proxyTarget
  36. * Sets the proxy target.
  37. *
  38. * @see \PHPUnit_Framework_TestCase::getMock
  39. * @see https://github.com/sebastianbergmann/phpunit/wiki/Release-Announcement-for-PHPUnit-5.4.0
  40. *
  41. * @return \PHPUnit_Framework_MockObject_MockObject
  42. *
  43. * @deprecated in Drupal 8.5.0 and will be removed before Drupal 9.0.0.
  44. * Use \Drupal\Tests\PhpunitCompatibilityTrait::createMock() instead.
  45. *
  46. * @see https://www.drupal.org/node/2907725
  47. */
  48. public function getMock($originalClassName, $methods = [], array $arguments = [], $mockClassName = '', $callOriginalConstructor = TRUE, $callOriginalClone = TRUE, $callAutoload = TRUE, $cloneArguments = FALSE, $callOriginalMethods = FALSE, $proxyTarget = NULL) {
  49. if (!$this->supports('getMock')) {
  50. $mock = $this->getMockBuilder($originalClassName)
  51. ->setMethods($methods)
  52. ->setConstructorArgs($arguments)
  53. ->setMockClassName($mockClassName)
  54. ->setProxyTarget($proxyTarget);
  55. if ($callOriginalConstructor) {
  56. $mock->enableOriginalConstructor();
  57. }
  58. else {
  59. $mock->disableOriginalConstructor();
  60. }
  61. if ($callOriginalClone) {
  62. $mock->enableOriginalClone();
  63. }
  64. else {
  65. $mock->disableOriginalClone();
  66. }
  67. if ($callAutoload) {
  68. $mock->enableAutoload();
  69. }
  70. else {
  71. $mock->disableAutoload();
  72. }
  73. if ($cloneArguments) {
  74. $mock->enableArgumentCloning();
  75. }
  76. else {
  77. $mock->disableArgumentCloning();
  78. }
  79. if ($callOriginalMethods) {
  80. $mock->enableProxyingToOriginalMethods();
  81. }
  82. else {
  83. $mock->disableProxyingToOriginalMethods();
  84. }
  85. return $mock->getMock();
  86. }
  87. else {
  88. return parent::getMock($originalClassName, $methods, $arguments, $mockClassName, $callOriginalConstructor, $callOriginalClone, $callAutoload, $cloneArguments, $callOriginalMethods, $proxyTarget);
  89. }
  90. }
  91. /**
  92. * Returns a mock object for the specified class using the available method.
  93. *
  94. * The createMock method does not exist in PHPUnit 4. To provide forward
  95. * compatibility this trait provides the createMock method and uses createMock
  96. * if this method is available on the parent class or falls back to getMock if
  97. * it isn't.
  98. *
  99. * @param string $originalClassName
  100. * Name of the class to mock.
  101. *
  102. * @see \PHPUnit_Framework_TestCase::getMock
  103. *
  104. * @return \PHPUnit_Framework_MockObject_MockObject
  105. */
  106. public function createMock($originalClassName) {
  107. if ($this->supports('createMock')) {
  108. return parent::createMock($originalClassName);
  109. }
  110. else {
  111. return $this->getMock($originalClassName, [], [], '', FALSE, FALSE);
  112. }
  113. }
  114. /**
  115. * Compatibility layer for PHPUnit 6 to support PHPUnit 4 code.
  116. *
  117. * @param mixed $class
  118. * The expected exception class.
  119. * @param string $message
  120. * The expected exception message.
  121. * @param int $exception_code
  122. * The expected exception code.
  123. */
  124. public function setExpectedException($class, $message = '', $exception_code = NULL) {
  125. if (method_exists($this, 'expectException')) {
  126. $this->expectException($class);
  127. if (!empty($message)) {
  128. $this->expectExceptionMessage($message);
  129. }
  130. if ($exception_code !== NULL) {
  131. $this->expectExceptionCode($exception_code);
  132. }
  133. }
  134. else {
  135. parent::setExpectedException($class, $message, $exception_code);
  136. }
  137. }
  138. /**
  139. * Checks if the trait is used in a class that has a method.
  140. *
  141. * @param string $method
  142. * Method to check.
  143. *
  144. * @return bool
  145. * TRUE if the method is supported, FALSE if not.
  146. */
  147. private function supports($method) {
  148. // Get the parent class of the currently running test class.
  149. $parent = get_parent_class($this);
  150. // Ensure that the method_exists() check on the createMock method is carried
  151. // out on the first parent of $this that does not have access to this
  152. // trait's methods. This is because the trait also has a method called
  153. // createMock(). Most often the check will be made on
  154. // \PHPUnit\Framework\TestCase.
  155. while (method_exists($parent, 'supports')) {
  156. $parent = get_parent_class($parent);
  157. }
  158. return method_exists($parent, $method);
  159. }
  160. }