class EntityUnitTest in Drupal 8
Same name and namespace in other branches
- 9 core/tests/Drupal/Tests/Core/Entity/EntityUnitTest.php \Drupal\Tests\Core\Entity\EntityUnitTest
- 10 core/tests/Drupal/Tests/Core/Entity/EntityUnitTest.php \Drupal\Tests\Core\Entity\EntityUnitTest
@coversDefaultClass \Drupal\Core\Entity\Entity @group Entity @group Access
Hierarchy
- class \Drupal\Tests\UnitTestCase extends \PHPUnit\Framework\TestCase uses PhpunitCompatibilityTrait
- class \Drupal\Tests\Core\Entity\EntityUnitTest uses ExpectDeprecationTrait
Expanded class hierarchy of EntityUnitTest
File
- core/
tests/ Drupal/ Tests/ Core/ Entity/ EntityUnitTest.php, line 21
Namespace
Drupal\Tests\Core\EntityView source
class EntityUnitTest extends UnitTestCase {
use ExpectDeprecationTrait;
/**
* The entity under test.
*
* @var \Drupal\Core\Entity\Entity|\PHPUnit\Framework\MockObject\MockObject
*/
protected $entity;
/**
* The entity type used for testing.
*
* @var \Drupal\Core\Entity\EntityTypeInterface|\PHPUnit\Framework\MockObject\MockObject
*/
protected $entityType;
/**
* The entity type manager used for testing.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface|\PHPUnit\Framework\MockObject\MockObject
*/
protected $entityTypeManager;
/**
* The ID of the type of the entity under test.
*
* @var string
*/
protected $entityTypeId;
/**
* The route provider used for testing.
*
* @var \Drupal\Core\Routing\RouteProvider|\PHPUnit\Framework\MockObject\MockObject
*/
protected $routeProvider;
/**
* The UUID generator used for testing.
*
* @var \Drupal\Component\Uuid\UuidInterface|\PHPUnit\Framework\MockObject\MockObject
*/
protected $uuid;
/**
* The language manager.
*
* @var \Drupal\Core\Language\LanguageManagerInterface|\PHPUnit\Framework\MockObject\MockObject
*/
protected $languageManager;
/**
* The mocked cache tags invalidator.
*
* @var \Drupal\Core\Cache\CacheTagsInvalidatorInterface|\PHPUnit\Framework\MockObject\MockObject
*/
protected $cacheTagsInvalidator;
/**
* The entity values.
*
* @var array
*/
protected $values;
/**
* {@inheritdoc}
*/
protected function setUp() {
$this->values = [
'id' => 1,
'langcode' => 'en',
'uuid' => '3bb9ee60-bea5-4622-b89b-a63319d10b3a',
];
$this->entityTypeId = $this
->randomMachineName();
$this->entityType = $this
->createMock('\\Drupal\\Core\\Entity\\EntityTypeInterface');
$this->entityType
->expects($this
->any())
->method('getListCacheTags')
->willReturn([
$this->entityTypeId . '_list',
]);
$this->entityTypeManager = $this
->getMockForAbstractClass(EntityTypeManagerInterface::class);
$this->entityTypeManager
->expects($this
->any())
->method('getDefinition')
->with($this->entityTypeId)
->will($this
->returnValue($this->entityType));
$this->uuid = $this
->createMock('\\Drupal\\Component\\Uuid\\UuidInterface');
$this->languageManager = $this
->createMock('\\Drupal\\Core\\Language\\LanguageManagerInterface');
$this->languageManager
->expects($this
->any())
->method('getLanguage')
->with('en')
->will($this
->returnValue(new Language([
'id' => 'en',
])));
$this->cacheTagsInvalidator = $this
->createMock('Drupal\\Core\\Cache\\CacheTagsInvalidator');
$container = new ContainerBuilder();
// Ensure that Entity doesn't use the deprecated entity.manager service.
$container
->set('entity.manager', NULL);
$container
->set('entity_type.manager', $this->entityTypeManager);
$container
->set('uuid', $this->uuid);
$container
->set('language_manager', $this->languageManager);
$container
->set('cache_tags.invalidator', $this->cacheTagsInvalidator);
\Drupal::setContainer($container);
$this->entity = $this
->getMockForAbstractClass('\\Drupal\\Core\\Entity\\EntityBase', [
$this->values,
$this->entityTypeId,
]);
}
/**
* @covers ::id
*/
public function testId() {
$this
->assertSame($this->values['id'], $this->entity
->id());
}
/**
* @covers ::uuid
*/
public function testUuid() {
$this
->assertSame($this->values['uuid'], $this->entity
->uuid());
}
/**
* @covers ::isNew
* @covers ::enforceIsNew
*/
public function testIsNew() {
// We provided an ID, so the entity is not new.
$this
->assertFalse($this->entity
->isNew());
// Force it to be new.
$this
->assertSame($this->entity, $this->entity
->enforceIsNew());
$this
->assertTrue($this->entity
->isNew());
}
/**
* @covers ::getEntityType
*/
public function testGetEntityType() {
$this
->assertSame($this->entityType, $this->entity
->getEntityType());
}
/**
* @covers ::bundle
*/
public function testBundle() {
$this
->assertSame($this->entityTypeId, $this->entity
->bundle());
}
/**
* @covers ::label
* @group legacy
*/
public function testLabel() {
$this
->addExpectedDeprecationMessage('Entity type ' . $this->entityTypeId . ' defines a label callback. Support for that is deprecated in drupal:8.0.0 and will be removed in drupal:9.0.0. Override the EntityInterface::label() method instead. See https://www.drupal.org/node/3050794');
// Make a mock with one method that we use as the entity's uri_callback. We
// check that it is called, and that the entity's label is the callback's
// return value.
$callback_label = $this
->randomMachineName();
$property_label = $this
->randomMachineName();
$callback_container = $this
->createMock(get_class());
$callback_container
->expects($this
->once())
->method(__FUNCTION__)
->will($this
->returnValue($callback_label));
$this->entityType
->expects($this
->at(0))
->method('get')
->with('label_callback')
->will($this
->returnValue([
$callback_container,
__FUNCTION__,
]));
$this->entityType
->expects($this
->at(2))
->method('getKey')
->with('label')
->will($this
->returnValue('label'));
// Set a dummy property on the entity under test to test that the label can
// be returned form a property if there is no callback.
$this->entityTypeManager
->expects($this
->at(1))
->method('getDefinition')
->with($this->entityTypeId)
->will($this
->returnValue([
'entity_keys' => [
'label' => 'label',
],
]));
$this->entity->label = $property_label;
$this
->assertSame($callback_label, $this->entity
->label());
$this
->assertSame($property_label, $this->entity
->label());
}
/**
* @covers ::access
*/
public function testAccess() {
$access = $this
->createMock('\\Drupal\\Core\\Entity\\EntityAccessControlHandlerInterface');
$operation = $this
->randomMachineName();
$access
->expects($this
->at(0))
->method('access')
->with($this->entity, $operation)
->will($this
->returnValue(AccessResult::allowed()));
$access
->expects($this
->at(1))
->method('createAccess')
->will($this
->returnValue(AccessResult::allowed()));
$this->entityTypeManager
->expects($this
->exactly(2))
->method('getAccessControlHandler')
->will($this
->returnValue($access));
$this
->assertEquals(AccessResult::allowed(), $this->entity
->access($operation));
$this
->assertEquals(AccessResult::allowed(), $this->entity
->access('create'));
}
/**
* @covers ::language
*/
public function testLanguage() {
$this->entityType
->expects($this
->any())
->method('getKey')
->will($this
->returnValueMap([
[
'langcode',
'langcode',
],
]));
$this
->assertSame('en', $this->entity
->language()
->getId());
}
/**
* Setup for the tests of the ::load() method.
*/
public function setupTestLoad() {
// Base our mocked entity on a real entity class so we can test if calling
// Entity::load() on the base class will bubble up to an actual entity.
$this->entityTypeId = 'entity_test_mul';
$methods = get_class_methods(EntityTestMul::class);
unset($methods[array_search('load', $methods)]);
unset($methods[array_search('loadMultiple', $methods)]);
unset($methods[array_search('create', $methods)]);
$this->entity = $this
->getMockBuilder(EntityTestMul::class)
->disableOriginalConstructor()
->setMethods($methods)
->getMock();
}
/**
* @covers ::load
*
* Tests Entity::load() when called statically on a subclass of Entity.
*/
public function testLoad() {
$this
->setupTestLoad();
$class_name = get_class($this->entity);
$entity_type_repository = $this
->getMockForAbstractClass(EntityTypeRepositoryInterface::class);
$entity_type_repository
->expects($this
->once())
->method('getEntityTypeFromClass')
->with($class_name)
->willReturn($this->entityTypeId);
$storage = $this
->createMock(EntityStorageInterface::class);
$storage
->expects($this
->once())
->method('load')
->with(1)
->will($this
->returnValue($this->entity));
$this->entityTypeManager
->expects($this
->once())
->method('getStorage')
->with($this->entityTypeId)
->will($this
->returnValue($storage));
\Drupal::getContainer()
->set('entity_type.repository', $entity_type_repository);
// Call Entity::load statically and check that it returns the mock entity.
$this
->assertSame($this->entity, $class_name::load(1));
}
/**
* @covers ::loadMultiple
*
* Tests Entity::loadMultiple() when called statically on a subclass of
* Entity.
*/
public function testLoadMultiple() {
$this
->setupTestLoad();
$class_name = get_class($this->entity);
$entity_type_repository = $this
->getMockForAbstractClass(EntityTypeRepositoryInterface::class);
$entity_type_repository
->expects($this
->once())
->method('getEntityTypeFromClass')
->with($class_name)
->willReturn($this->entityTypeId);
$storage = $this
->createMock(EntityStorageInterface::class);
$storage
->expects($this
->once())
->method('loadMultiple')
->with([
1,
])
->will($this
->returnValue([
1 => $this->entity,
]));
$this->entityTypeManager
->expects($this
->once())
->method('getStorage')
->with($this->entityTypeId)
->will($this
->returnValue($storage));
\Drupal::getContainer()
->set('entity_type.repository', $entity_type_repository);
// Call Entity::loadMultiple statically and check that it returns the mock
// entity.
$this
->assertSame([
1 => $this->entity,
], $class_name::loadMultiple([
1,
]));
}
/**
* @covers ::create
*/
public function testCreate() {
$this
->setupTestLoad();
$class_name = get_class($this->entity);
$entity_type_repository = $this
->getMockForAbstractClass(EntityTypeRepositoryInterface::class);
$entity_type_repository
->expects($this
->once())
->method('getEntityTypeFromClass')
->with($class_name)
->willReturn($this->entityTypeId);
$storage = $this
->createMock(EntityStorageInterface::class);
$storage
->expects($this
->once())
->method('create')
->with([])
->will($this
->returnValue($this->entity));
$this->entityTypeManager
->expects($this
->once())
->method('getStorage')
->with($this->entityTypeId)
->will($this
->returnValue($storage));
\Drupal::getContainer()
->set('entity_type.repository', $entity_type_repository);
// Call Entity::create() statically and check that it returns the mock
// entity.
$this
->assertSame($this->entity, $class_name::create([]));
}
/**
* @covers ::save
*/
public function testSave() {
$storage = $this
->createMock('\\Drupal\\Core\\Entity\\EntityStorageInterface');
$storage
->expects($this
->once())
->method('save')
->with($this->entity);
$this->entityTypeManager
->expects($this
->once())
->method('getStorage')
->with($this->entityTypeId)
->will($this
->returnValue($storage));
$this->entity
->save();
}
/**
* @covers ::delete
*/
public function testDelete() {
$this->entity->id = $this
->randomMachineName();
$storage = $this
->createMock('\\Drupal\\Core\\Entity\\EntityStorageInterface');
// Testing the argument of the delete() method consumes too much memory.
$storage
->expects($this
->once())
->method('delete');
$this->entityTypeManager
->expects($this
->once())
->method('getStorage')
->with($this->entityTypeId)
->will($this
->returnValue($storage));
$this->entity
->delete();
}
/**
* @covers ::getEntityTypeId
*/
public function testGetEntityTypeId() {
$this
->assertSame($this->entityTypeId, $this->entity
->getEntityTypeId());
}
/**
* @covers ::preSave
*/
public function testPreSave() {
// This method is internal, so check for errors on calling it only.
$storage = $this
->createMock('\\Drupal\\Core\\Entity\\EntityStorageInterface');
// Our mocked entity->preSave() returns NULL, so assert that.
$this
->assertNull($this->entity
->preSave($storage));
}
/**
* @covers ::postSave
*/
public function testPostSave() {
$this->cacheTagsInvalidator
->expects($this
->at(0))
->method('invalidateTags')
->with([
// List cache tag.
$this->entityTypeId . '_list',
]);
$this->cacheTagsInvalidator
->expects($this
->at(1))
->method('invalidateTags')
->with([
// Own cache tag.
$this->entityTypeId . ':' . $this->values['id'],
// List cache tag.
$this->entityTypeId . '_list',
]);
// This method is internal, so check for errors on calling it only.
$storage = $this
->createMock('\\Drupal\\Core\\Entity\\EntityStorageInterface');
// A creation should trigger the invalidation of the "list" cache tag.
$this->entity
->postSave($storage, FALSE);
// An update should trigger the invalidation of both the "list" and the
// "own" cache tags.
$this->entity
->postSave($storage, TRUE);
}
/**
* @covers ::postSave
*/
public function testPostSaveBundle() {
$this->cacheTagsInvalidator
->expects($this
->at(0))
->method('invalidateTags')
->with([
// List cache tag.
$this->entityTypeId . '_list',
$this->entityTypeId . '_list:' . $this->entity
->bundle(),
]);
$this->cacheTagsInvalidator
->expects($this
->at(1))
->method('invalidateTags')
->with([
// Own cache tag.
$this->entityTypeId . ':' . $this->values['id'],
// List cache tag.
$this->entityTypeId . '_list',
$this->entityTypeId . '_list:' . $this->entity
->bundle(),
]);
$this->entityType
->expects($this
->atLeastOnce())
->method('hasKey')
->with('bundle')
->willReturn(TRUE);
// This method is internal, so check for errors on calling it only.
$storage = $this
->createMock('\\Drupal\\Core\\Entity\\EntityStorageInterface');
// A creation should trigger the invalidation of the global list cache tag
// and the one for the bundle.
$this->entity
->postSave($storage, FALSE);
// An update should trigger the invalidation of the "list", bundle list and
// the "own" cache tags.
$this->entity
->postSave($storage, TRUE);
}
/**
* @covers ::preCreate
*/
public function testPreCreate() {
// This method is internal, so check for errors on calling it only.
$storage = $this
->createMock('\\Drupal\\Core\\Entity\\EntityStorageInterface');
$values = [];
// Our mocked entity->preCreate() returns NULL, so assert that.
$this
->assertNull($this->entity
->preCreate($storage, $values));
}
/**
* @covers ::postCreate
*/
public function testPostCreate() {
// This method is internal, so check for errors on calling it only.
$storage = $this
->createMock('\\Drupal\\Core\\Entity\\EntityStorageInterface');
// Our mocked entity->postCreate() returns NULL, so assert that.
$this
->assertNull($this->entity
->postCreate($storage));
}
/**
* @covers ::preDelete
*/
public function testPreDelete() {
// This method is internal, so check for errors on calling it only.
$storage = $this
->createMock('\\Drupal\\Core\\Entity\\EntityStorageInterface');
// Our mocked entity->preDelete() returns NULL, so assert that.
$this
->assertNull($this->entity
->preDelete($storage, [
$this->entity,
]));
}
/**
* @covers ::postDelete
*/
public function testPostDelete() {
$this->cacheTagsInvalidator
->expects($this
->once())
->method('invalidateTags')
->with([
$this->entityTypeId . ':' . $this->values['id'],
$this->entityTypeId . '_list',
]);
$storage = $this
->createMock('\\Drupal\\Core\\Entity\\EntityStorageInterface');
$storage
->expects($this
->once())
->method('getEntityType')
->willReturn($this->entityType);
$entities = [
$this->values['id'] => $this->entity,
];
$this->entity
->postDelete($storage, $entities);
}
/**
* @covers ::postDelete
*/
public function testPostDeleteBundle() {
$this->cacheTagsInvalidator
->expects($this
->once())
->method('invalidateTags')
->with([
$this->entityTypeId . ':' . $this->values['id'],
$this->entityTypeId . '_list',
$this->entityTypeId . '_list:' . $this->entity
->bundle(),
]);
$this->entityType
->expects($this
->atLeastOnce())
->method('hasKey')
->with('bundle')
->willReturn(TRUE);
$storage = $this
->createMock('\\Drupal\\Core\\Entity\\EntityStorageInterface');
$storage
->expects($this
->once())
->method('getEntityType')
->willReturn($this->entityType);
$entities = [
$this->values['id'] => $this->entity,
];
$this->entity
->postDelete($storage, $entities);
}
/**
* @covers ::postLoad
*/
public function testPostLoad() {
// This method is internal, so check for errors on calling it only.
$storage = $this
->createMock('\\Drupal\\Core\\Entity\\EntityStorageInterface');
$entities = [
$this->entity,
];
// Our mocked entity->postLoad() returns NULL, so assert that.
$this
->assertNull($this->entity
->postLoad($storage, $entities));
}
/**
* @covers ::referencedEntities
*/
public function testReferencedEntities() {
$this
->assertSame([], $this->entity
->referencedEntities());
}
/**
* @covers ::getCacheTags
* @covers ::getCacheTagsToInvalidate
* @covers ::addCacheTags
*/
public function testCacheTags() {
// Ensure that both methods return the same by default.
$this
->assertEquals([
$this->entityTypeId . ':' . 1,
], $this->entity
->getCacheTags());
$this
->assertEquals([
$this->entityTypeId . ':' . 1,
], $this->entity
->getCacheTagsToInvalidate());
// Add an additional cache tag and make sure only getCacheTags() returns
// that.
$this->entity
->addCacheTags([
'additional_cache_tag',
]);
// EntityTypeId is random so it can shift order. We need to duplicate the
// sort from \Drupal\Core\Cache\Cache::mergeTags().
$tags = [
'additional_cache_tag',
$this->entityTypeId . ':' . 1,
];
sort($tags);
$this
->assertEquals($tags, $this->entity
->getCacheTags());
$this
->assertEquals([
$this->entityTypeId . ':' . 1,
], $this->entity
->getCacheTagsToInvalidate());
}
/**
* @covers ::getCacheContexts
* @covers ::addCacheContexts
*/
public function testCacheContexts() {
$cache_contexts_manager = $this
->getMockBuilder('Drupal\\Core\\Cache\\Context\\CacheContextsManager')
->disableOriginalConstructor()
->getMock();
$cache_contexts_manager
->method('assertValidTokens')
->willReturn(TRUE);
$container = new ContainerBuilder();
$container
->set('cache_contexts_manager', $cache_contexts_manager);
\Drupal::setContainer($container);
// There are no cache contexts by default.
$this
->assertEquals([], $this->entity
->getCacheContexts());
// Add an additional cache context.
$this->entity
->addCacheContexts([
'user',
]);
$this
->assertEquals([
'user',
], $this->entity
->getCacheContexts());
}
/**
* @covers ::getCacheMaxAge
* @covers ::mergeCacheMaxAge
*/
public function testCacheMaxAge() {
// Cache max age is permanent by default.
$this
->assertEquals(Cache::PERMANENT, $this->entity
->getCacheMaxAge());
// Set two cache max ages, the lower value is the one that needs to be
// returned.
$this->entity
->mergeCacheMaxAge(600);
$this->entity
->mergeCacheMaxAge(1800);
$this
->assertEquals(600, $this->entity
->getCacheMaxAge());
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
EntityUnitTest:: |
protected | property | The mocked cache tags invalidator. | |
EntityUnitTest:: |
protected | property | The entity under test. | |
EntityUnitTest:: |
protected | property | The entity type used for testing. | |
EntityUnitTest:: |
protected | property | The ID of the type of the entity under test. | |
EntityUnitTest:: |
protected | property | The entity type manager used for testing. | |
EntityUnitTest:: |
protected | property | The language manager. | |
EntityUnitTest:: |
protected | property | The route provider used for testing. | |
EntityUnitTest:: |
protected | property | The UUID generator used for testing. | |
EntityUnitTest:: |
protected | property | The entity values. | |
EntityUnitTest:: |
protected | function |
Overrides UnitTestCase:: |
|
EntityUnitTest:: |
public | function | Setup for the tests of the ::load() method. | |
EntityUnitTest:: |
public | function | @covers ::access | |
EntityUnitTest:: |
public | function | @covers ::bundle | |
EntityUnitTest:: |
public | function | @covers ::getCacheContexts @covers ::addCacheContexts | |
EntityUnitTest:: |
public | function | @covers ::getCacheMaxAge @covers ::mergeCacheMaxAge | |
EntityUnitTest:: |
public | function | @covers ::getCacheTags @covers ::getCacheTagsToInvalidate @covers ::addCacheTags | |
EntityUnitTest:: |
public | function | @covers ::create | |
EntityUnitTest:: |
public | function | @covers ::delete | |
EntityUnitTest:: |
public | function | @covers ::getEntityType | |
EntityUnitTest:: |
public | function | @covers ::getEntityTypeId | |
EntityUnitTest:: |
public | function | @covers ::id | |
EntityUnitTest:: |
public | function | @covers ::isNew @covers ::enforceIsNew | |
EntityUnitTest:: |
public | function | @covers ::label @group legacy | |
EntityUnitTest:: |
public | function | @covers ::language | |
EntityUnitTest:: |
public | function | @covers ::load | |
EntityUnitTest:: |
public | function | @covers ::loadMultiple | |
EntityUnitTest:: |
public | function | @covers ::postCreate | |
EntityUnitTest:: |
public | function | @covers ::postDelete | |
EntityUnitTest:: |
public | function | @covers ::postDelete | |
EntityUnitTest:: |
public | function | @covers ::postLoad | |
EntityUnitTest:: |
public | function | @covers ::postSave | |
EntityUnitTest:: |
public | function | @covers ::postSave | |
EntityUnitTest:: |
public | function | @covers ::preCreate | |
EntityUnitTest:: |
public | function | @covers ::preDelete | |
EntityUnitTest:: |
public | function | @covers ::preSave | |
EntityUnitTest:: |
public | function | @covers ::referencedEntities | |
EntityUnitTest:: |
public | function | @covers ::save | |
EntityUnitTest:: |
public | function | @covers ::uuid | |
ExpectDeprecationTrait:: |
protected | function | Sets an expected deprecation message. | |
ExpectDeprecationTrait:: |
protected | function | Sets an expected deprecation message. | |
ExpectDeprecationTrait:: |
public | function | Sets expected deprecation messages. | |
ExpectDeprecationTrait:: |
private | function | Gets the SymfonyTestsListenerTrait. | |
PhpunitCompatibilityTrait:: |
public | function | Returns a mock object for the specified class using the available method. | |
PhpunitCompatibilityTrait:: |
public | function | Compatibility layer for PHPUnit 6 to support PHPUnit 4 code. | |
UnitTestCase:: |
protected | property | The random generator. | |
UnitTestCase:: |
protected | property | The app root. | 1 |
UnitTestCase:: |
protected | function | Asserts if two arrays are equal by sorting them first. | |
UnitTestCase:: |
protected | function | Mocks a block with a block plugin. | 1 |
UnitTestCase:: |
protected | function | Returns a stub class resolver. | |
UnitTestCase:: |
public | function | Returns a stub config factory that behaves according to the passed array. | |
UnitTestCase:: |
public | function | Returns a stub config storage that returns the supplied configuration. | |
UnitTestCase:: |
protected | function | Sets up a container with a cache tags invalidator. | |
UnitTestCase:: |
protected | function | Gets the random generator for the utility methods. | |
UnitTestCase:: |
public | function | Returns a stub translation manager that just returns the passed string. | |
UnitTestCase:: |
public | function | Generates a unique random string containing letters and numbers. |