Sometimes I find that I end up having to do lots of mocking just to make the class testable, especially if it is interacting with the Entity API. For example, if I have code like this:
$taxonomy_term_storage = $this->entityTypeManager->getStorage('taxonomy_term'); $category = $taxonomy_term_storage->load($product_category_tid); $category_atlas_key = $category->get('field_name_key')->getValue();
So now, to mock the return value of one field I need to do all of this:
$fieldItemListMock = $this->getMockBuilder('\Drupal\Core\Field\FieldItemListInterface') ->disableOriginalConstructor() ->getMock(); $fieldItemListMock->expects($this->any()) ->method('getValue') ->willReturn('foo'); $fieldableEntityMock = $this->getMockBuilder('\Drupal\Core\Entity\FieldableEntityInterface') ->disableOriginalConstructor() ->getMock() $fieldableEntityMock->expects($this->any()) ->method('get') ->willReturn($fieldItemListMock); $entityStorageMock = $this->getMockBuilder('\Drupal\Core\Entity\EntityStorageInterface') ->disableOriginalConstructor() ->getMock(); $entityStorageMock->expects($this->any()) ->method('load') ->willReturn($fieldableEntityMock); $this->entityTypeManagerMock->expects($this->any()) ->method('getStorage') ->willReturn($entityStorageMock);
As far as I'm aware I've done everything as I'm supposed to, injecting external dependencies via the constructor but it still seems like way too much effort. The problem gets exponentially worse when I'm working with multiple fields or other people's code who haven't injected dependencies properly. So I end up having to create a partial mock of the class I'm testing.
Browsing through core and contrib modules I notice that there seem to be more Kernel tests than Unit tests, which seems contrary to the testing pyramid
Which makes it seem like they have also found unit tests too hard to set up.
So I'm wondering, is it better to just write Kernel tests / Browser tests for classes that interact with the Entity API or am I simply writing my code wrong, which is making it hard to unit test?