web-dev-qa-db-ja.com

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-> valueは機能しません

これが私のテストクラスのセットアップ関数です:

/**
   * {@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);

  }
4
oknate

次の例では、PHPUnitモックオブジェクトを使用して動作するはずです。

最初のモックFieldItemListInterface __getマジックメソッド。

$fieldDescMock = $this->getMockBuilder('\Drupal\Core\Field\FieldItemListInterface')
  ->disableOriginalConstructor()
  ->getMock();
$fieldDescMock->expects($this->any())
  ->method('__get')
  ->with('value')
  ->willReturn('blah');

次に、Node/ContentEntityBase __getマジックメソッドをモックします。

$node->expects($this->any())
  ->method('__get')
  ->with('field_description')
  ->willReturn($fieldDescMock);
5
mradcliffe

Mradcliffeの回答 うまくいきました、これが私のコード例です:

これが私のために働いたものです:

$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を使用できないためと思われる。

1
oknate