Как имитировать значение поля узла для phpunit?
Я работаю над проектом, в котором нам нужно обеспечить покрытие кода с помощью phpunit.
У меня есть метод, который включает в себя этот код:
$node = \Drupal::entityTypeManager()->getStorage('node')->load($node_id);
$form['data-title']['#value'] = $node->label();
$form['data-description']['#value'] = $node->field_description->value;
Поэтому мне нужно смоделировать объект узла.
Я могу заставить работать метку узла, но не field_description->значение
Вот моя функция настройки в моем тестовом классе:
/**
* {@inheritdoc}
*/
protected function setUp() {
$container = new Container();
$container->set('string_translation', $this->getStringTranslationStub());
$renderer = $this->getMockBuilder(Renderer::class)
->disableOriginalConstructor()
->getMock();
$renderer
->method('render')
->willReturn('Hello world');
$container->set('renderer', $renderer);
// Mock entity type manager.
$this->entityTypeManager = $this->getMockBuilder(EntityTypeManagerInterface::class)
->disableOriginalConstructor()
->getMock();
// Mock a node and add the label to it.
$node = $this->getMockBuilder(Node::class)
->disableOriginalConstructor()
->getMock();
$node->expects($this->any())
->method('label')
->willReturn('shaken not stirred');
$node->expects($this->any())
->method('access')
->willReturn(TRUE);
$node->expects($this->any())
->method('id')
->willReturn(1);
// @todo figure out how to add a field to a mock node.
/*$field_description = new \stdClass();
$field_description->value = 'This is a description';
$node->set('field_description', $field_description);*/
$node_storage = $this->getMockBuilder(EntityStorageInterface::class)
->disableOriginalConstructor()
->getMock();
$node_storage->expects($this->any())
->method('load')
->willReturn($node);
$this->entityTypeManager->expects($this->any())
->method('getStorage')
->willReturn($node_storage);
$this->uuid = $this->getMockBuilder(UuidInterface::class)
->disableOriginalConstructor()
->getMock();
$container->set('entity_type.manager', $this->entityTypeManager);
$entity_repository = $this->getMockBuilder(EntityRepository::class)
->disableOriginalConstructor()
->getMock();
$entity_repository->expects($this->any())
->method('getTranslationFromContext')
->willReturn($node);
$container->set('entity.repository', $entity_repository);
\Drupal::setContainer($container);
$this->form = MyForm::create($container);
}
2 answers
Следующее должно работать с использованием макетных объектов PHPUnit, как в вашем примере.
Первый макет интерфейса fielditemlist __получить магический метод.
$fieldDescMock = $this->getMockBuilder('\Drupal\Core\Field\FieldItemListInterface')
->disableOriginalConstructor()
->getMock();
$fieldDescMock->expects($this->any())
->method('__get')
->with('value')
->willReturn('blah');
Затем издевайтесь над узлом/базой данных содержимого __получите магический метод.
$node->expects($this->any())
->method('__get')
->with('field_description')
->willReturn($fieldDescMock);
Ответ Мрадклиффа сработал для меня, вот мой пример кода:
Вот что в итоге получилось у меня:
$this->node = $this->getMockBuilder(Node::class)
->disableOriginalConstructor()
->getMock();
$fieldAdsEnabled = $this->getMockBuilder(FieldItemListInterface::class)
->disableOriginalConstructor()
->getMock();
$fieldAdsEnabled->expects($this->any())
->method('__get')
->with('value')
->willReturn(1);
$this->node->expects($this->any())
->method('__get')
->with('field_widgets_enabed')
->willReturn($fieldAdsEnabled);
Примечание: для меня помогло использование объекта Node, а не nodeInterface. Я подозреваю, потому что в противном случае __get недоступен.