3 namespace Drupal\Tests;
5 use Drupal\Component\FileCache\FileCacheFactory;
6 use Drupal\Component\Utility\Random;
7 use Drupal\Core\Cache\CacheTagsInvalidatorInterface;
8 use Drupal\Core\DependencyInjection\ContainerBuilder;
9 use Drupal\Core\StringTranslation\TranslatableMarkup;
10 use Drupal\Core\StringTranslation\PluralTranslatableMarkup;
11 use PHPUnit\Framework\TestCase;
14 * Provides a base class and helpers for Drupal unit tests.
18 abstract class UnitTestCase extends TestCase {
20 use PhpunitCompatibilityTrait;
23 * The random generator.
25 * @var \Drupal\Component\Utility\Random
27 protected $randomGenerator;
39 protected function setUp() {
41 // Ensure that an instantiated container in the global state of \Drupal from
42 // a previous test does not leak into this test.
43 \Drupal::unsetContainer();
45 // Ensure that the NullFileCache implementation is used for the FileCache as
46 // unit tests should not be relying on caches implicitly.
47 FileCacheFactory::setConfiguration([FileCacheFactory::DISABLE_CACHE => TRUE]);
48 // Ensure that FileCacheFactory has a prefix.
49 FileCacheFactory::setPrefix('prefix');
51 $this->root = dirname(dirname(substr(__DIR__, 0, -strlen(__NAMESPACE__))));
55 * Generates a unique random string containing letters and numbers.
58 * Length of random string to generate.
61 * Randomly generated unique string.
63 * @see \Drupal\Component\Utility\Random::name()
65 public function randomMachineName($length = 8) {
66 return $this->getRandomGenerator()->name($length, TRUE);
70 * Gets the random generator for the utility methods.
72 * @return \Drupal\Component\Utility\Random
73 * The random generator
75 protected function getRandomGenerator() {
76 if (!is_object($this->randomGenerator)) {
77 $this->randomGenerator = new Random();
79 return $this->randomGenerator;
83 * Asserts if two arrays are equal by sorting them first.
85 * @param array $expected
86 * @param array $actual
87 * @param string $message
89 protected function assertArrayEquals(array $expected, array $actual, $message = NULL) {
92 $this->assertEquals($expected, $actual, $message);
96 * Returns a stub config factory that behaves according to the passed in array.
98 * Use this to generate a config factory that will return the desired values
99 * for the given config names.
101 * @param array $configs
102 * An associative array of configuration settings whose keys are configuration
103 * object names and whose values are key => value arrays for the configuration
104 * object in question. Defaults to an empty array.
106 * @return \PHPUnit_Framework_MockObject_MockBuilder
107 * A MockBuilder object for the ConfigFactory with the desired return values.
109 public function getConfigFactoryStub(array $configs = []) {
110 $config_get_map = [];
111 $config_editable_map = [];
112 // Construct the desired configuration object stubs, each with its own
113 // desired return map.
114 foreach ($configs as $config_name => $config_values) {
116 foreach ($config_values as $key => $value) {
117 $map[] = [$key, $value];
119 // Also allow to pass in no argument.
120 $map[] = ['', $config_values];
122 $immutable_config_object = $this->getMockBuilder('Drupal\Core\Config\ImmutableConfig')
123 ->disableOriginalConstructor()
125 $immutable_config_object->expects($this->any())
127 ->will($this->returnValueMap($map));
128 $config_get_map[] = [$config_name, $immutable_config_object];
130 $mutable_config_object = $this->getMockBuilder('Drupal\Core\Config\Config')
131 ->disableOriginalConstructor()
133 $mutable_config_object->expects($this->any())
135 ->will($this->returnValueMap($map));
136 $config_editable_map[] = [$config_name, $mutable_config_object];
138 // Construct a config factory with the array of configuration object stubs
139 // as its return map.
140 $config_factory = $this->createMock('Drupal\Core\Config\ConfigFactoryInterface');
141 $config_factory->expects($this->any())
143 ->will($this->returnValueMap($config_get_map));
144 $config_factory->expects($this->any())
145 ->method('getEditable')
146 ->will($this->returnValueMap($config_editable_map));
147 return $config_factory;
151 * Returns a stub config storage that returns the supplied configuration.
153 * @param array $configs
154 * An associative array of configuration settings whose keys are
155 * configuration object names and whose values are key => value arrays
156 * for the configuration object in question.
158 * @return \Drupal\Core\Config\StorageInterface
159 * A mocked config storage.
161 public function getConfigStorageStub(array $configs) {
162 $config_storage = $this->createMock('Drupal\Core\Config\NullStorage');
163 $config_storage->expects($this->any())
165 ->will($this->returnValue(array_keys($configs)));
167 foreach ($configs as $name => $config) {
168 $config_storage->expects($this->any())
170 ->with($this->equalTo($name))
171 ->will($this->returnValue($config));
173 return $config_storage;
177 * Mocks a block with a block plugin.
179 * @param string $machine_name
180 * The machine name of the block plugin.
182 * @return \Drupal\block\BlockInterface|\PHPUnit_Framework_MockObject_MockObject
185 protected function getBlockMockWithMachineName($machine_name) {
186 $plugin = $this->getMockBuilder('Drupal\Core\Block\BlockBase')
187 ->disableOriginalConstructor()
189 $plugin->expects($this->any())
190 ->method('getMachineNameSuggestion')
191 ->will($this->returnValue($machine_name));
193 $block = $this->getMockBuilder('Drupal\block\Entity\Block')
194 ->disableOriginalConstructor()
196 $block->expects($this->any())
197 ->method('getPlugin')
198 ->will($this->returnValue($plugin));
203 * Returns a stub translation manager that just returns the passed string.
205 * @return \PHPUnit_Framework_MockObject_MockObject|\Drupal\Core\StringTranslation\TranslationInterface
206 * A mock translation object.
208 public function getStringTranslationStub() {
209 $translation = $this->createMock('Drupal\Core\StringTranslation\TranslationInterface');
210 $translation->expects($this->any())
211 ->method('translate')
212 ->willReturnCallback(function ($string, array $args = [], array $options = []) use ($translation) {
213 return new TranslatableMarkup($string, $args, $options, $translation);
215 $translation->expects($this->any())
216 ->method('translateString')
217 ->willReturnCallback(function (TranslatableMarkup $wrapper) {
218 return $wrapper->getUntranslatedString();
220 $translation->expects($this->any())
221 ->method('formatPlural')
222 ->willReturnCallback(function ($count, $singular, $plural, array $args = [], array $options = []) use ($translation) {
223 $wrapper = new PluralTranslatableMarkup($count, $singular, $plural, $args, $options, $translation);
230 * Sets up a container with a cache tags invalidator.
232 * @param \Drupal\Core\Cache\CacheTagsInvalidatorInterface $cache_tags_validator
233 * The cache tags invalidator.
235 * @return \Symfony\Component\DependencyInjection\ContainerInterface|\PHPUnit_Framework_MockObject_MockObject
236 * The container with the cache tags invalidator service.
238 protected function getContainerWithCacheTagsInvalidator(CacheTagsInvalidatorInterface $cache_tags_validator) {
239 $container = $this->createMock('Symfony\Component\DependencyInjection\ContainerInterface');
240 $container->expects($this->any())
242 ->with('cache_tags.invalidator')
243 ->will($this->returnValue($cache_tags_validator));
245 \Drupal::setContainer($container);
250 * Returns a stub class resolver.
252 * @return \Drupal\Core\DependencyInjection\ClassResolverInterface|\PHPUnit_Framework_MockObject_MockObject
253 * The class resolver stub.
255 protected function getClassResolverStub() {
256 $class_resolver = $this->createMock('Drupal\Core\DependencyInjection\ClassResolverInterface');
257 $class_resolver->expects($this->any())
258 ->method('getInstanceFromDefinition')
259 ->will($this->returnCallback(function ($class) {
260 if (is_subclass_of($class, 'Drupal\Core\DependencyInjection\ContainerInjectionInterface')) {
261 return $class::create(new ContainerBuilder());
267 return $class_resolver;