You are here

abstract class UnitTestCase in Drupal 9

Same name and namespace in other branches
  1. 8 core/tests/Drupal/Tests/UnitTestCase.php \Drupal\Tests\UnitTestCase

Provides a base class and helpers for Drupal unit tests.

Using Symfony's dump() function() in Unit tests will produce output on the command line.

Hierarchy

Expanded class hierarchy of UnitTestCase

Related topics

554 files declare their use of UnitTestCase
AcceptHeaderMatcherTest.php in core/tests/Drupal/Tests/Core/Routing/AcceptHeaderMatcherTest.php
AccessAwareRouterTest.php in core/tests/Drupal/Tests/Core/Routing/AccessAwareRouterTest.php
AccessGroupAndTest.php in core/modules/block_content/tests/src/Unit/Access/AccessGroupAndTest.php
AccessManagerTest.php in core/tests/Drupal/Tests/Core/Access/AccessManagerTest.php
Contains \Drupal\Tests\Core\Access\AccessManagerTest.
AccessResultForbiddenTest.php in core/tests/Drupal/Tests/Core/Access/AccessResultForbiddenTest.php

... See full list

File

core/tests/Drupal/Tests/UnitTestCase.php, line 26

Namespace

Drupal\Tests
View source
abstract class UnitTestCase extends TestCase {
  use PhpUnitWarnings;
  use PhpUnitCompatibilityTrait;
  use ExpectDeprecationTrait;

  /**
   * The random generator.
   *
   * @var \Drupal\Component\Utility\Random
   */
  protected $randomGenerator;

  /**
   * The app root.
   *
   * @var string
   */
  protected $root;

  /**
   * {@inheritdoc}
   */
  public static function setUpBeforeClass() {
    parent::setUpBeforeClass();
    VarDumper::setHandler(TestVarDumper::class . '::cliHandler');
  }

  /**
   * {@inheritdoc}
   */
  protected function setUp() {
    parent::setUp();

    // Ensure that an instantiated container in the global state of \Drupal from
    // a previous test does not leak into this test.
    \Drupal::unsetContainer();

    // Ensure that the NullFileCache implementation is used for the FileCache as
    // unit tests should not be relying on caches implicitly.
    FileCacheFactory::setConfiguration([
      FileCacheFactory::DISABLE_CACHE => TRUE,
    ]);

    // Ensure that FileCacheFactory has a prefix.
    FileCacheFactory::setPrefix('prefix');
    $this->root = dirname(substr(__DIR__, 0, -strlen(__NAMESPACE__)), 2);
  }

  /**
   * Generates a unique random string containing letters and numbers.
   *
   * @param int $length
   *   Length of random string to generate.
   *
   * @return string
   *   Randomly generated unique string.
   *
   * @see \Drupal\Component\Utility\Random::name()
   */
  public function randomMachineName($length = 8) {
    return $this
      ->getRandomGenerator()
      ->name($length, TRUE);
  }

  /**
   * Gets the random generator for the utility methods.
   *
   * @return \Drupal\Component\Utility\Random
   *   The random generator
   */
  protected function getRandomGenerator() {
    if (!is_object($this->randomGenerator)) {
      $this->randomGenerator = new Random();
    }
    return $this->randomGenerator;
  }

  /**
   * Asserts if two arrays are equal by sorting them first.
   *
   * @param array $expected
   * @param array $actual
   * @param string $message
   *
   * @deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use
   *   ::assertEquals, ::assertEqualsCanonicalizing, or ::assertSame instead.
   *
   * @see https://www.drupal.org/node/3136304
   */
  protected function assertArrayEquals(array $expected, array $actual, $message = NULL) {
    @trigger_error(__METHOD__ . "() is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use ::assertEquals(), ::assertEqualsCanonicalizing(), or ::assertSame() instead. See https://www.drupal.org/node/3136304", E_USER_DEPRECATED);
    ksort($expected);
    ksort($actual);
    $this
      ->assertEquals($expected, $actual, !empty($message) ? $message : '');
  }

  /**
   * Returns a stub config factory that behaves according to the passed array.
   *
   * Use this to generate a config factory that will return the desired values
   * for the given config names.
   *
   * @param array $configs
   *   An associative array of configuration settings whose keys are
   *   configuration object names and whose values are key => value arrays for
   *   the configuration object in question. Defaults to an empty array.
   *
   * @return \PHPUnit\Framework\MockObject\MockBuilder
   *   A MockBuilder object for the ConfigFactory with the desired return
   *   values.
   */
  public function getConfigFactoryStub(array $configs = []) {
    $config_get_map = [];
    $config_editable_map = [];

    // Construct the desired configuration object stubs, each with its own
    // desired return map.
    foreach ($configs as $config_name => $config_values) {

      // Define a closure over the $config_values, which will be used as a
      // returnCallback below. This function will mimic
      // \Drupal\Core\Config\Config::get and allow using dotted keys.
      $config_get = function ($key = '') use ($config_values) {

        // Allow to pass in no argument.
        if (empty($key)) {
          return $config_values;
        }

        // See if we have the key as is.
        if (isset($config_values[$key])) {
          return $config_values[$key];
        }
        $parts = explode('.', $key);
        $value = NestedArray::getValue($config_values, $parts, $key_exists);
        return $key_exists ? $value : NULL;
      };
      $immutable_config_object = $this
        ->getMockBuilder('Drupal\\Core\\Config\\ImmutableConfig')
        ->disableOriginalConstructor()
        ->getMock();
      $immutable_config_object
        ->expects($this
        ->any())
        ->method('get')
        ->willReturnCallback($config_get);
      $config_get_map[] = [
        $config_name,
        $immutable_config_object,
      ];
      $mutable_config_object = $this
        ->getMockBuilder('Drupal\\Core\\Config\\Config')
        ->disableOriginalConstructor()
        ->getMock();
      $mutable_config_object
        ->expects($this
        ->any())
        ->method('get')
        ->willReturnCallback($config_get);
      $config_editable_map[] = [
        $config_name,
        $mutable_config_object,
      ];
    }

    // Construct a config factory with the array of configuration object stubs
    // as its return map.
    $config_factory = $this
      ->createMock('Drupal\\Core\\Config\\ConfigFactoryInterface');
    $config_factory
      ->expects($this
      ->any())
      ->method('get')
      ->willReturnMap($config_get_map);
    $config_factory
      ->expects($this
      ->any())
      ->method('getEditable')
      ->willReturnMap($config_editable_map);
    return $config_factory;
  }

  /**
   * Returns a stub config storage that returns the supplied configuration.
   *
   * @param array $configs
   *   An associative array of configuration settings whose keys are
   *   configuration object names and whose values are key => value arrays
   *   for the configuration object in question.
   *
   * @return \Drupal\Core\Config\StorageInterface
   *   A mocked config storage.
   */
  public function getConfigStorageStub(array $configs) {
    $config_storage = $this
      ->createMock('Drupal\\Core\\Config\\NullStorage');
    $config_storage
      ->expects($this
      ->any())
      ->method('listAll')
      ->will($this
      ->returnValue(array_keys($configs)));
    foreach ($configs as $name => $config) {
      $config_storage
        ->expects($this
        ->any())
        ->method('read')
        ->with($this
        ->equalTo($name))
        ->will($this
        ->returnValue($config));
    }
    return $config_storage;
  }

  /**
   * Returns a stub translation manager that just returns the passed string.
   *
   * @return \PHPUnit\Framework\MockObject\MockObject|\Drupal\Core\StringTranslation\TranslationInterface
   *   A mock translation object.
   */
  public function getStringTranslationStub() {
    $translation = $this
      ->createMock('Drupal\\Core\\StringTranslation\\TranslationInterface');
    $translation
      ->expects($this
      ->any())
      ->method('translate')
      ->willReturnCallback(function ($string, array $args = [], array $options = []) use ($translation) {
      return new TranslatableMarkup($string, $args, $options, $translation);
    });
    $translation
      ->expects($this
      ->any())
      ->method('translateString')
      ->willReturnCallback(function (TranslatableMarkup $wrapper) {
      return $wrapper
        ->getUntranslatedString();
    });
    $translation
      ->expects($this
      ->any())
      ->method('formatPlural')
      ->willReturnCallback(function ($count, $singular, $plural, array $args = [], array $options = []) use ($translation) {
      $wrapper = new PluralTranslatableMarkup($count, $singular, $plural, $args, $options, $translation);
      return $wrapper;
    });
    return $translation;
  }

  /**
   * Sets up a container with a cache tags invalidator.
   *
   * @param \Drupal\Core\Cache\CacheTagsInvalidatorInterface $cache_tags_validator
   *   The cache tags invalidator.
   *
   * @return \Symfony\Component\DependencyInjection\ContainerInterface|\PHPUnit\Framework\MockObject\MockObject
   *   The container with the cache tags invalidator service.
   */
  protected function getContainerWithCacheTagsInvalidator(CacheTagsInvalidatorInterface $cache_tags_validator) {
    $container = $this
      ->createMock('Symfony\\Component\\DependencyInjection\\ContainerInterface');
    $container
      ->expects($this
      ->any())
      ->method('get')
      ->with('cache_tags.invalidator')
      ->will($this
      ->returnValue($cache_tags_validator));
    \Drupal::setContainer($container);
    return $container;
  }

  /**
   * Returns a stub class resolver.
   *
   * @return \Drupal\Core\DependencyInjection\ClassResolverInterface|\PHPUnit\Framework\MockObject\MockObject
   *   The class resolver stub.
   */
  protected function getClassResolverStub() {
    $class_resolver = $this
      ->createMock('Drupal\\Core\\DependencyInjection\\ClassResolverInterface');
    $class_resolver
      ->expects($this
      ->any())
      ->method('getInstanceFromDefinition')
      ->willReturnCallback(function ($class) {
      if (is_subclass_of($class, 'Drupal\\Core\\DependencyInjection\\ContainerInjectionInterface')) {
        return $class::create(new ContainerBuilder());
      }
      else {
        return new $class();
      }
    });
    return $class_resolver;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
PhpUnitWarnings::$deprecationWarnings private static property Deprecation warnings from PHPUnit to raise with @trigger_error().
PhpUnitWarnings::addWarning public function Converts PHPUnit deprecation warnings to E_USER_DEPRECATED.
UnitTestCase::$randomGenerator protected property The random generator.
UnitTestCase::$root protected property The app root. 1
UnitTestCase::assertArrayEquals Deprecated protected function Asserts if two arrays are equal by sorting them first.
UnitTestCase::getClassResolverStub protected function Returns a stub class resolver.
UnitTestCase::getConfigFactoryStub public function Returns a stub config factory that behaves according to the passed array.
UnitTestCase::getConfigStorageStub public function Returns a stub config storage that returns the supplied configuration.
UnitTestCase::getContainerWithCacheTagsInvalidator protected function Sets up a container with a cache tags invalidator.
UnitTestCase::getRandomGenerator protected function Gets the random generator for the utility methods.
UnitTestCase::getStringTranslationStub public function Returns a stub translation manager that just returns the passed string.
UnitTestCase::randomMachineName public function Generates a unique random string containing letters and numbers.
UnitTestCase::setUp protected function 308
UnitTestCase::setUpBeforeClass public static function