3

I have a node type already created on my site. I want to create a node with this node type in my PHP Unit test since I am using my database but I am getting errors. It seems like I may have to recreate the node type in the PHP Unit test first and then create it.

Is it possible to create a node without creating the node type in PHP Unit?

Here is the command I am running to run a PHP Unit test:

php ./core/scripts/run-tests.sh --verbose --php /usr/local/bin/php —-dburl mysql://drupal:drupal@mariadb/drupal --url http://nginx --class "Drupal\my_module\Tests\ExpenseTest"

This is the error:

    Status    Group      Filename          Line Function
    --------------------------------------------------------------------------------
    Fail      Completion ExpenseTest.php     64 Drupal\my_module\Tests\ExpenseTes
        The test did not complete due to a fatal error.
    Pass      Other      ExpenseTest.php     55 Drupal\my_module\Tests\ExpenseTes
        Enabled modules: node, paragraphs
    Fail      run-tests. Unknown              0 Unknown
        FATAL Drupal\my_module\Tests\ExpenseTest: test runner returned a non-zero
        error code (255).
    Fail      Fatal erro Unknown              0 Unknown
        [17-Feb-2018 17:36:34 Australia/Sydney] PHP Fatal error:  Uncaught Error:
        Call to a member function referencedEntities() on null in
        /var/www/html/web/modules/custom/my_module/src/Expense.php:116
    Fail      Fatal erro Unknown              0 Unknown
        Stack trace:
    Fail      Fatal erro Unknown              0 Unknown
        #0
        /var/www/html/web/modules/custom/my_module/src/Tests/ExpenseTest.php(65):
        Drupal\my_module\Expense->__construct(Object(Drupal\node\Entity\Node))
    Fail      Fatal erro Unknown              0 Unknown
        #1 /var/www/html/web/core/modules/simpletest/src/TestBase.php(963):
        Drupal\my_module\Tests\ExpenseTest->testValidation()
    Fail      Fatal erro Unknown              0 Unknown
        #2 /var/www/html/web/core/scripts/run-tests.sh(804):
        Drupal\simpletest\TestBase->run(Array)
    Fail      Fatal erro Unknown              0 Unknown
        #3 /var/www/html/web/core/scripts/run-tests.sh(67):
        simpletest_script_run_one_test('44', 'Drupal\\reo_expe...')
    Fail      Fatal erro Unknown              0 Unknown
        #4 {main}
    Fail      Fatal erro Unknown              0 Unknown
        thrown in /var/www/html/web/modules/custom/my_module/src/Expense.php on
        line 116
    /var/www/html/web $

This is my code:

<?php

namespace Drupal\my_module\Tests;

use Drupal\simpletest\WebTestBase;
use Drupal\node\Entity\Node;
use Drupal\paragraphs\Entity\Paragraph;
use Drupal\my_module\Expense;

/**
 * Tests views contextual links on nodes.
 *
 * @group reo_expense
 */
class ExpenseTest extends WebTestBase {

  /**
   * Node object
   *
   * @var /Drupal\node\Entity\Node
   */
  protected $node;

  /**
   * Modules to enable.
   *
   * @var array
   */
  public static $modules = ['node', 'paragraphs'];

  /**
   * {@inheritdoc}
   */
  protected function setUp() {
    parent::setUp();

    $this->node = $this->createMyNode();
  }

  /**
   * Tests contextual links.
   */
  public function testValidation() {
    $expense = new Expense($this->node);
    $this->assertEqual($expense->getRegionId(), 4);
  }

  /**
   * Create Expense node.
   */
  public function createMyNode() {
    // Populate defaults array.
    $settings = [
      'title' => 'asdfasdf',
      'type' => 'expense',
      'uid' => \Drupal::currentUser()->id(),
    ];
    $node = Node::create($settings);
    return $node;
  }
}

1 Answer 1

2

When you create a node, you need to reference a bundle that already exists. In your case, you are referencing a bundle (expense) that is created from a custom module, but that module is not installed.

If you look at the tests for the Node module, you will notice they always install the Node module. In the test classes that expand the NodeTestBase class, that is done from that class. In other test classes, for example the NodeFieldAccessTest class (a Kernel test), that is done directly by that test class.

In your case, changing the list of modules to install to the following one would solve the issue.

  /**
   * Modules to enable.
   *
   * @var array
   */
  public static $modules = ['node', 'paragraphs', 'my_module'];

From the error messages, I take the machine name of the module creating the content type is my_module. If that is not correct, replace my_module with the correct machine name.

9
  • You could try to export your node's configuration and import it in your test. However, node type definition is quite easy if you have done it 2-3 times via inheriting from NodeTestBase or KernelTestBase
    – jepster
    Commented Feb 17, 2018 at 14:49
  • The node bundle expense was created manually via UI in Drupal. I am trying to create a node with that node type in my PHP Unit test without recreating the node bundle in PhpUnit. (Would have to add all the fields etc..) How would you recommend doing this?
    – albertski
    Commented Feb 17, 2018 at 14:52
  • @albertski Create a test module that defines that content type, and add it to the list of modules to install during the test. The test module can define the new content type in a .yml file placed in the config/optional directory. See the node.type.forum.yml file as example of module defining a new content type that is created when the module is installed.
    – avpaderno
    Commented Feb 17, 2018 at 14:55
  • @kiamlaluno Thanks, I think creating a test module with the content type is right answer. Is there an easy way to do this? The only way I can think of is to look for all the config files manually and put them in my test modules config folder manually.
    – albertski
    Commented Feb 17, 2018 at 15:02
  • The content type can also be created from the test class, though.
    – avpaderno
    Commented Feb 17, 2018 at 15:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.