class EntityUnitTest
Tests Drupal\Core\Entity\EntityBase.
Attributes
#[CoversClass(EntityBase::class)]
#[Group('Entity')]
#[Group('Access')]
Hierarchy
- class \Drupal\Tests\UnitTestCase uses \Drupal\Tests\PhpUnitCompatibilityTrait, \Prophecy\PhpUnit\ProphecyTrait, \Drupal\TestTools\Extension\DeprecationBridge\ExpectDeprecationTrait, \Drupal\Tests\RandomGeneratorTrait extends \PHPUnit\Framework\TestCase
- class \Drupal\Tests\Core\Entity\EntityUnitTest extends \Drupal\Tests\UnitTestCase
Expanded class hierarchy of EntityUnitTest
File
-
core/
tests/ Drupal/ Tests/ Core/ Entity/ EntityUnitTest.php, line 24
Namespace
Drupal\Tests\Core\EntityView source
class EntityUnitTest extends UnitTestCase {
/**
* The entity under test.
*
* @var \Drupal\Core\Entity\EntityInterface|\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|\Prophecy\Prophecy\ObjectProphecy
*/
protected $cacheTagsInvalidator;
/**
* The entity values.
*
* @var array
*/
protected $values;
/**
* {@inheritdoc}
*/
protected function setUp() : void {
parent::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->entityType
->expects($this->any())
->method('getBundleListCacheTags')
->with($this->entityTypeId)
->willReturn([
$this->entityTypeId . '_list:' . $this->entityTypeId,
]);
$this->entityTypeManager = $this->createMock(EntityTypeManagerInterface::class);
$this->entityTypeManager
->expects($this->any())
->method('getDefinition')
->with($this->entityTypeId)
->willReturn($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')
->willReturn(new Language([
'id' => 'en',
]));
$this->cacheTagsInvalidator = $this->prophesize('Drupal\\Core\\Cache\\CacheTagsInvalidator');
$container = new ContainerBuilder();
$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
->reveal());
\Drupal::setContainer($container);
$this->entity = new StubEntityBase($this->values, $this->entityTypeId);
}
/**
* Tests id.
*
* @legacy-covers ::id
*/
public function testId() : void {
$this->assertSame($this->values['id'], $this->entity
->id());
}
/**
* Tests uuid.
*
* @legacy-covers ::uuid
*/
public function testUuid() : void {
$this->assertSame($this->values['uuid'], $this->entity
->uuid());
}
/**
* Tests is new.
*
* @legacy-covers ::isNew
* @legacy-covers ::enforceIsNew
*/
public function testIsNew() : void {
// 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());
}
/**
* Tests get entity type.
*
* @legacy-covers ::getEntityType
*/
public function testGetEntityType() : void {
$this->assertSame($this->entityType, $this->entity
->getEntityType());
}
/**
* Tests bundle.
*
* @legacy-covers ::bundle
*/
public function testBundle() : void {
$this->assertSame($this->entityTypeId, $this->entity
->bundle());
}
/**
* Tests label.
*
* @legacy-covers ::label
*/
public function testLabel() : void {
$property_label = $this->randomMachineName();
$this->entityType
->expects($this->atLeastOnce())
->method('getKey')
->with('label')
->willReturn('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->atLeastOnce())
->method('getDefinition')
->with($this->entityTypeId)
->willReturn([
'entity_keys' => [
'label' => 'label',
],
]);
$this->entity->label = $property_label;
$this->assertSame($property_label, $this->entity
->label());
}
/**
* Tests access.
*
* @legacy-covers ::access
*/
public function testAccess() : void {
$access = $this->createMock('\\Drupal\\Core\\Entity\\EntityAccessControlHandlerInterface');
$operation = $this->randomMachineName();
$access->expects($this->once())
->method('access')
->with($this->entity, $operation)
->willReturn(AccessResult::allowed());
$access->expects($this->once())
->method('createAccess')
->willReturn(AccessResult::allowed());
$this->entityTypeManager
->expects($this->exactly(2))
->method('getAccessControlHandler')
->willReturn($access);
$this->assertEquals(AccessResult::allowed(), $this->entity
->access($operation));
$this->assertEquals(AccessResult::allowed(), $this->entity
->access('create'));
}
/**
* Tests language.
*
* @legacy-covers ::language
*/
public function testLanguage() : void {
$this->entityType
->expects($this->any())
->method('getKey')
->willReturnMap([
[
'langcode',
'langcode',
],
]);
$this->assertSame('en', $this->entity
->language()
->getId());
}
/**
* Setup for the tests of the ::load() method.
*/
public function setupTestLoad() : void {
// Base our mocked entity on a real entity class so we can test if calling
// EntityBase::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()
->onlyMethods($methods)
->getMock();
}
/**
* Tests EntityBase::load().
*
* When called statically on a subclass of Entity.
*
* @legacy-covers ::load
*/
public function testLoad() : void {
$this->setupTestLoad();
$class_name = get_class($this->entity);
$entity_type_repository = $this->createMock(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)
->willReturn($this->entity);
$this->entityTypeManager
->expects($this->once())
->method('getStorage')
->with($this->entityTypeId)
->willReturn($storage);
\Drupal::getContainer()->set('entity_type.repository', $entity_type_repository);
// Call EntityBase::load statically and check that it returns the mock
// entity.
$this->assertSame($this->entity, $class_name::load(1));
}
/**
* Tests EntityBase::loadMultiple().
*
* When called statically on a subclass of Entity.
*
* @legacy-covers ::loadMultiple
*/
public function testLoadMultiple() : void {
$this->setupTestLoad();
$class_name = get_class($this->entity);
$entity_type_repository = $this->createMock(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,
])
->willReturn([
1 => $this->entity,
]);
$this->entityTypeManager
->expects($this->once())
->method('getStorage')
->with($this->entityTypeId)
->willReturn($storage);
\Drupal::getContainer()->set('entity_type.repository', $entity_type_repository);
// Call EntityBase::loadMultiple() statically and check that it returns the
// mock entity.
$this->assertSame([
1 => $this->entity,
], $class_name::loadMultiple([
1,
]));
}
/**
* Tests create.
*
* @legacy-covers ::create
*/
public function testCreate() : void {
$this->setupTestLoad();
$class_name = get_class($this->entity);
$entity_type_repository = $this->createMock(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([])
->willReturn($this->entity);
$this->entityTypeManager
->expects($this->once())
->method('getStorage')
->with($this->entityTypeId)
->willReturn($storage);
\Drupal::getContainer()->set('entity_type.repository', $entity_type_repository);
// Call EntityBase::create() statically and check that it returns the mock
// entity.
$this->assertSame($this->entity, $class_name::create([]));
}
/**
* Tests save.
*
* @legacy-covers ::save
*/
public function testSave() : void {
$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)
->willReturn($storage);
$this->entity
->save();
}
/**
* Tests delete.
*
* @legacy-covers ::delete
*/
public function testDelete() : void {
$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)
->willReturn($storage);
$this->entity
->delete();
}
/**
* Tests get entity type id.
*
* @legacy-covers ::getEntityTypeId
*/
public function testGetEntityTypeId() : void {
$this->assertSame($this->entityTypeId, $this->entity
->getEntityTypeId());
}
/**
* Tests pre save.
*
* @legacy-covers ::preSave
*/
public function testPreSave() : void {
// 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));
}
/**
* Tests post save.
*
* @legacy-covers ::postSave
*/
public function testPostSave() : void {
// 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);
$this->cacheTagsInvalidator
->invalidateTags([
$this->entityTypeId . '_list',
])
->shouldHaveBeenCalledOnce();
// An update should trigger the invalidation of both the "list" and the
// "own" cache tags.
$this->entity
->postSave($storage, TRUE);
$this->cacheTagsInvalidator
->invalidateTags([
$this->entityTypeId . '_list',
$this->entityTypeId . ':' . $this->values['id'],
])
->shouldHaveBeenCalledOnce();
}
/**
* Tests post save bundle.
*
* @legacy-covers ::postSave
*/
public function testPostSaveBundle() : void {
$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);
$this->cacheTagsInvalidator
->invalidateTags([
$this->entityTypeId . '_list',
$this->entityTypeId . '_list:' . $this->entity
->bundle(),
])
->shouldHaveBeenCalledOnce();
// An update should trigger the invalidation of the "list", bundle list and
// the "own" cache tags.
$this->entity
->postSave($storage, TRUE);
$this->cacheTagsInvalidator
->invalidateTags([
$this->entityTypeId . '_list',
$this->entityTypeId . '_list:' . $this->entity
->bundle(),
$this->entityTypeId . ':' . $this->values['id'],
])
->shouldHaveBeenCalledOnce();
}
/**
* Tests pre create.
*
* @legacy-covers ::preCreate
*/
public function testPreCreate() : void {
// 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));
}
/**
* Tests post create.
*
* @legacy-covers ::postCreate
*/
public function testPostCreate() : void {
// 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));
}
/**
* Tests pre delete.
*
* @legacy-covers ::preDelete
*/
public function testPreDelete() : void {
// 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,
]));
}
/**
* Tests post delete.
*
* @legacy-covers ::postDelete
*/
public function testPostDelete() : void {
$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);
$this->cacheTagsInvalidator
->invalidateTags([
$this->entityTypeId . '_list',
$this->entityTypeId . ':' . $this->values['id'],
])
->shouldHaveBeenCalledOnce();
}
/**
* Tests post delete bundle.
*
* @legacy-covers ::postDelete
*/
public function testPostDeleteBundle() : void {
$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);
// We avoid asserting on the order of array values, just that the values
// all exist.
$this->cacheTagsInvalidator
->invalidateTags(Argument::allOf(Argument::containing($this->entityTypeId . '_list'), Argument::containing($this->entityTypeId . ':' . $this->values['id']), Argument::containing($this->entityTypeId . '_list:' . $this->entity
->bundle())))
->shouldHaveBeenCalledOnce();
}
/**
* Tests post load.
*
* @legacy-covers ::postLoad
*/
public function testPostLoad() : void {
// 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));
}
/**
* Tests referenced entities.
*
* @legacy-covers ::referencedEntities
*/
public function testReferencedEntities() : void {
$this->assertSame([], $this->entity
->referencedEntities());
}
/**
* Tests cache tags.
*
* @legacy-covers ::getCacheTags
* @legacy-covers ::getCacheTagsToInvalidate
* @legacy-covers ::addCacheTags
*/
public function testCacheTags() : void {
// Ensure that both methods return the same by default.
$this->assertEqualsCanonicalizing([
$this->entityTypeId . ':' . 1,
], $this->entity
->getCacheTags());
$this->assertEqualsCanonicalizing([
$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 = [
$this->entityTypeId . ':' . 1,
'additional_cache_tag',
];
$this->assertEqualsCanonicalizing($tags, $this->entity
->getCacheTags());
$this->assertEqualsCanonicalizing([
$this->entityTypeId . ':' . 1,
], $this->entity
->getCacheTagsToInvalidate());
}
/**
* Tests cache contexts.
*
* @legacy-covers ::getCacheContexts
* @legacy-covers ::addCacheContexts
*/
public function testCacheContexts() : void {
$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->assertEqualsCanonicalizing([], $this->entity
->getCacheContexts());
// Add an additional cache context.
$this->entity
->addCacheContexts([
'user',
]);
$this->assertEqualsCanonicalizing([
'user',
], $this->entity
->getCacheContexts());
}
/**
* Tests cache max age.
*
* @legacy-covers ::getCacheMaxAge
* @legacy-covers ::mergeCacheMaxAge
*/
public function testCacheMaxAge() : void {
// 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
| Title Sort descending | Modifiers | Object type | Summary | Overriden Title |
|---|---|---|---|---|
| EntityUnitTest::$cacheTagsInvalidator | protected | property | The mocked cache tags invalidator. | |
| EntityUnitTest::$entity | protected | property | The entity under test. | |
| EntityUnitTest::$entityType | protected | property | The entity type used for testing. | |
| EntityUnitTest::$entityTypeId | protected | property | The ID of the type of the entity under test. | |
| EntityUnitTest::$entityTypeManager | protected | property | The entity type manager used for testing. | |
| EntityUnitTest::$languageManager | protected | property | The language manager. | |
| EntityUnitTest::$routeProvider | protected | property | The route provider used for testing. | |
| EntityUnitTest::$uuid | protected | property | The UUID generator used for testing. | |
| EntityUnitTest::$values | protected | property | The entity values. | |
| EntityUnitTest::setUp | protected | function | Overrides UnitTestCase::setUp | |
| EntityUnitTest::setupTestLoad | public | function | Setup for the tests of the ::load() method. | |
| EntityUnitTest::testAccess | public | function | Tests access. | |
| EntityUnitTest::testBundle | public | function | Tests bundle. | |
| EntityUnitTest::testCacheContexts | public | function | Tests cache contexts. | |
| EntityUnitTest::testCacheMaxAge | public | function | Tests cache max age. | |
| EntityUnitTest::testCacheTags | public | function | Tests cache tags. | |
| EntityUnitTest::testCreate | public | function | Tests create. | |
| EntityUnitTest::testDelete | public | function | Tests delete. | |
| EntityUnitTest::testGetEntityType | public | function | Tests get entity type. | |
| EntityUnitTest::testGetEntityTypeId | public | function | Tests get entity type id. | |
| EntityUnitTest::testId | public | function | Tests id. | |
| EntityUnitTest::testIsNew | public | function | Tests is new. | |
| EntityUnitTest::testLabel | public | function | Tests label. | |
| EntityUnitTest::testLanguage | public | function | Tests language. | |
| EntityUnitTest::testLoad | public | function | Tests EntityBase::load(). | |
| EntityUnitTest::testLoadMultiple | public | function | Tests EntityBase::loadMultiple(). | |
| EntityUnitTest::testPostCreate | public | function | Tests post create. | |
| EntityUnitTest::testPostDelete | public | function | Tests post delete. | |
| EntityUnitTest::testPostDeleteBundle | public | function | Tests post delete bundle. | |
| EntityUnitTest::testPostLoad | public | function | Tests post load. | |
| EntityUnitTest::testPostSave | public | function | Tests post save. | |
| EntityUnitTest::testPostSaveBundle | public | function | Tests post save bundle. | |
| EntityUnitTest::testPreCreate | public | function | Tests pre create. | |
| EntityUnitTest::testPreDelete | public | function | Tests pre delete. | |
| EntityUnitTest::testPreSave | public | function | Tests pre save. | |
| EntityUnitTest::testReferencedEntities | public | function | Tests referenced entities. | |
| EntityUnitTest::testSave | public | function | Tests save. | |
| EntityUnitTest::testUuid | public | function | Tests uuid. | |
| ExpectDeprecationTrait::expectDeprecation | public | function | Adds an expected deprecation. | |
| ExpectDeprecationTrait::setUpErrorHandler | public | function | Sets up the test error handler. | |
| ExpectDeprecationTrait::tearDownErrorHandler | public | function | Tears down the test error handler. | |
| RandomGeneratorTrait::getRandomGenerator | protected | function | Gets the random generator for the utility methods. | |
| RandomGeneratorTrait::randomMachineName | protected | function | Generates a unique random string containing letters and numbers. | |
| RandomGeneratorTrait::randomObject | public | function | Generates a random PHP object. | |
| RandomGeneratorTrait::randomString | public | function | Generates a pseudo-random string of ASCII characters of codes 32 to 126. | |
| UnitTestCase::$root | protected | property | The app root. | |
| 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::getContainerWithCacheTagsInvalidator | protected | function | Sets up a container with a cache tags invalidator. | |
| UnitTestCase::getStringTranslationStub | public | function | Returns a stub translation manager that just returns the passed string. | |
| UnitTestCase::setDebugDumpHandler | public static | function | Registers the dumper CLI handler when the DebugDump extension is enabled. | |
| UnitTestCase::setupMockIterator | protected | function | Set up a traversable class mock to return specific items when iterated. |
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.