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;
14 * Provides a base class and helpers for Drupal unit tests.
18 abstract class UnitTestCase extends \PHPUnit_Framework_TestCase {
21 * The random generator.
23 * @var \Drupal\Component\Utility\Random
25 protected $randomGenerator;
37 protected function setUp() {
39 // Ensure that an instantiated container in the global state of \Drupal from
40 // a previous test does not leak into this test.
41 \Drupal::unsetContainer();
43 // Ensure that the NullFileCache implementation is used for the FileCache as
44 // unit tests should not be relying on caches implicitly.
45 FileCacheFactory::setConfiguration([FileCacheFactory::DISABLE_CACHE => TRUE]);
46 // Ensure that FileCacheFactory has a prefix.
47 FileCacheFactory::setPrefix('prefix');
49 $this->root = dirname(dirname(substr(__DIR__, 0, -strlen(__NAMESPACE__))));
53 * Generates a unique random string containing letters and numbers.
56 * Length of random string to generate.
59 * Randomly generated unique string.
61 * @see \Drupal\Component\Utility\Random::name()
63 public function randomMachineName($length = 8) {
64 return $this->getRandomGenerator()->name($length, TRUE);
68 * Gets the random generator for the utility methods.
70 * @return \Drupal\Component\Utility\Random
71 * The random generator
73 protected function getRandomGenerator() {
74 if (!is_object($this->randomGenerator)) {
75 $this->randomGenerator = new Random();
77 return $this->randomGenerator;
81 * Asserts if two arrays are equal by sorting them first.
83 * @param array $expected
84 * @param array $actual
85 * @param string $message
87 protected function assertArrayEquals(array $expected, array $actual, $message = NULL) {
90 $this->assertEquals($expected, $actual, $message);
94 * Returns a stub config factory that behaves according to the passed in array.
96 * Use this to generate a config factory that will return the desired values
97 * for the given config names.
99 * @param array $configs
100 * An associative array of configuration settings whose keys are configuration
101 * object names and whose values are key => value arrays for the configuration
102 * object in question. Defaults to an empty array.
104 * @return \PHPUnit_Framework_MockObject_MockBuilder
105 * A MockBuilder object for the ConfigFactory with the desired return values.
107 public function getConfigFactoryStub(array $configs = []) {
108 $config_get_map = [];
109 $config_editable_map = [];
110 // Construct the desired configuration object stubs, each with its own
111 // desired return map.
112 foreach ($configs as $config_name => $config_values) {
114 foreach ($config_values as $key => $value) {
115 $map[] = [$key, $value];
117 // Also allow to pass in no argument.
118 $map[] = ['', $config_values];
120 $immutable_config_object = $this->getMockBuilder('Drupal\Core\Config\ImmutableConfig')
121 ->disableOriginalConstructor()
123 $immutable_config_object->expects($this->any())
125 ->will($this->returnValueMap($map));
126 $config_get_map[] = [$config_name, $immutable_config_object];
128 $mutable_config_object = $this->getMockBuilder('Drupal\Core\Config\Config')
129 ->disableOriginalConstructor()
131 $mutable_config_object->expects($this->any())
133 ->will($this->returnValueMap($map));
134 $config_editable_map[] = [$config_name, $mutable_config_object];
136 // Construct a config factory with the array of configuration object stubs
137 // as its return map.
138 $config_factory = $this->getMock('Drupal\Core\Config\ConfigFactoryInterface');
139 $config_factory->expects($this->any())
141 ->will($this->returnValueMap($config_get_map));
142 $config_factory->expects($this->any())
143 ->method('getEditable')
144 ->will($this->returnValueMap($config_editable_map));
145 return $config_factory;
149 * Returns a stub config storage that returns the supplied configuration.
151 * @param array $configs
152 * An associative array of configuration settings whose keys are
153 * configuration object names and whose values are key => value arrays
154 * for the configuration object in question.
156 * @return \Drupal\Core\Config\StorageInterface
157 * A mocked config storage.
159 public function getConfigStorageStub(array $configs) {
160 $config_storage = $this->getMock('Drupal\Core\Config\NullStorage');
161 $config_storage->expects($this->any())
163 ->will($this->returnValue(array_keys($configs)));
165 foreach ($configs as $name => $config) {
166 $config_storage->expects($this->any())
168 ->with($this->equalTo($name))
169 ->will($this->returnValue($config));
171 return $config_storage;
175 * Mocks a block with a block plugin.
177 * @param string $machine_name
178 * The machine name of the block plugin.
180 * @return \Drupal\block\BlockInterface|\PHPUnit_Framework_MockObject_MockObject
183 protected function getBlockMockWithMachineName($machine_name) {
184 $plugin = $this->getMockBuilder('Drupal\Core\Block\BlockBase')
185 ->disableOriginalConstructor()
187 $plugin->expects($this->any())
188 ->method('getMachineNameSuggestion')
189 ->will($this->returnValue($machine_name));
191 $block = $this->getMockBuilder('Drupal\block\Entity\Block')
192 ->disableOriginalConstructor()
194 $block->expects($this->any())
195 ->method('getPlugin')
196 ->will($this->returnValue($plugin));
201 * Returns a stub translation manager that just returns the passed string.
203 * @return \PHPUnit_Framework_MockObject_MockObject|\Drupal\Core\StringTranslation\TranslationInterface
204 * A mock translation object.
206 public function getStringTranslationStub() {
207 $translation = $this->getMock('Drupal\Core\StringTranslation\TranslationInterface');
208 $translation->expects($this->any())
209 ->method('translate')
210 ->willReturnCallback(function ($string, array $args = [], array $options = []) use ($translation) {
211 return new TranslatableMarkup($string, $args, $options, $translation);
213 $translation->expects($this->any())
214 ->method('translateString')
215 ->willReturnCallback(function (TranslatableMarkup $wrapper) {
216 return $wrapper->getUntranslatedString();
218 $translation->expects($this->any())
219 ->method('formatPlural')
220 ->willReturnCallback(function ($count, $singular, $plural, array $args = [], array $options = []) use ($translation) {
221 $wrapper = new PluralTranslatableMarkup($count, $singular, $plural, $args, $options, $translation);
228 * Sets up a container with a cache tags invalidator.
230 * @param \Drupal\Core\Cache\CacheTagsInvalidatorInterface $cache_tags_validator
231 * The cache tags invalidator.
233 * @return \Symfony\Component\DependencyInjection\ContainerInterface|\PHPUnit_Framework_MockObject_MockObject
234 * The container with the cache tags invalidator service.
236 protected function getContainerWithCacheTagsInvalidator(CacheTagsInvalidatorInterface $cache_tags_validator) {
237 $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface');
238 $container->expects($this->any())
240 ->with('cache_tags.invalidator')
241 ->will($this->returnValue($cache_tags_validator));
243 \Drupal::setContainer($container);
248 * Returns a stub class resolver.
250 * @return \Drupal\Core\DependencyInjection\ClassResolverInterface|\PHPUnit_Framework_MockObject_MockObject
251 * The class resolver stub.
253 protected function getClassResolverStub() {
254 $class_resolver = $this->getMock('Drupal\Core\DependencyInjection\ClassResolverInterface');
255 $class_resolver->expects($this->any())
256 ->method('getInstanceFromDefinition')
257 ->will($this->returnCallback(function ($class) {
258 if (is_subclass_of($class, 'Drupal\Core\DependencyInjection\ContainerInjectionInterface')) {
259 return $class::create(new ContainerBuilder());
265 return $class_resolver;