0

Here's the class I want to test:

class Thing {
  
    public function foo() {
      return \Drupal::entityQuery('node')->condition('body', 'blah')->execute();
    }
  
  }

And the test:

class footest extends \Drupal\KernelTests\KernelTestBase {

  public static $modules = ['node', 'user', 'field'];

 public function testFoo() {
   $thing = new Thing();
   \PHPUnit\Framework\assertEquals($thing->foo() ,4);
 }
}

Obviously this is not a real class or a real test, but they are pared down to the basics to demonstrate the issue.

When I run the test I get "Drupal\Core\Entity\Query\QueryException : 'body' not found".

If I replace "body" with "field_baz', a field that I know exists on at least some content types, I get "Drupal\Core\Entity\Query\QueryException : 'field_baz' not found".

Removing the condition entirely, so that the function body becomes:

return \Drupal::entityQuery('node')->execute();

produces "Drupal\Core\Database\DatabaseExceptionWrapper : SQLSTATE[42S02]: Base table or view not found: 1146 Table 'carbon.test65392739node' doesn't exist"

What am I doing wrong? How can I write tests for code that uses EntityQuery? Thanks!

1 Answer 1

2

Test classes that extend KernelTestBase needs to create the database tables in their setUp() method. See EntityDisplayTest::setUp(), for example, which creates the database tables for the Node entity.

  parent::setUp();
  $this->installEntitySchema('entity_test');
  $this->installEntitySchema('node');
  $this->installEntitySchema('user');
  $this->installConfig(['field', 'node', 'user']);

Setting $modules to the required modules is not sufficient for the database tables to be created. EntityDisplayTest itself sets EntityDisplayTest::$modules to ['field_ui', 'field', 'entity_test', 'user', 'text', 'field_test', 'node', 'system'] but then calls KernelTestBase::installEntitySchema() for the User and Node entities.

For database tables that are not for entities, there is KernelTestBase::installSchema(), which creates the database tables a module defines in its hook_schema() hook.

3
  • Thanks! This seems to have helped, but now I have another error: "Exception : Exception when installing config for module node, message was: No schema for system.action.node_delete_action"
    – naomi
    May 11, 2023 at 5:57
  • It means you need to create that database table with KernelTestBase::installConfig(). If then the exception is referring to the configuration schema, probably that is not sufficient.
    – apaderno
    May 11, 2023 at 7:12
  • Thanks. I'm struggling a great deal to find a way of writing automated tests for Drupal code that manipulates entities. Your answer solved the immediate issues that I asked about, but I ended up down another rabbit hole when it came to loading site config. This probably breaks the rules of stack exchange but do you offer paid help? I've noticed your name on a few Drupal testing questions so you seem to know what you are on about!
    – naomi
    May 11, 2023 at 16:36

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.