6

I have a custom module that defines a service and a custom content type. I have successfully written a Functional test for the service. Now, I'm seeing if I can write a Kernel test instead.

The issue that I'm encountering is that my custom content type has custom fields (naturally). When I create a piece of content of that type in the Kernel test environment, Drupal is not recognizing the custom fields.

  • I am using the EntityKernelTestBase.
  • I have set public static $modules = array('my_custom_module', 'node');

What piece(s) am I missing? I'm guessing there is some schema I need to say to install or some other method I need to call so that those custom fields are recognized.

<?php

namespace Drupal\Tests\my_custom_module\Kernel;

use Drupal\KernelTests\Core\Entity\EntityKernelTestBase;
use Drupal\node\Entity\Node;

/**
 * Tests the my custom service.
 *
 * @group my_custom_module
 */
class MyCustomServiceKernelTest extends EntityKernelTestBase {

  /**
   * Modules to install.
   *
   * @var array
   */
  public static $modules = array('my_custom_module', 'node');

  /**
   * {@inheritdoc}
   */
  public function setUp() {

    parent::setup();

    $user = $this->createUser();

    $container = \Drupal::getContainer();
    $container->get('current_user')->setAccount($user);

    // Create some aquifer pieces of content
    $node = Node::create(array(
      'title' => t('Some title'),
      'type' => 'my_custom_content_type',
      'language' => 'en',
      'field_my_custom_field_1' => 'Put stuff here',
      'field_my_custom_field_2' => 'more stuff',
      'field_my_custom_field' => 1000000,
    ));
    $node->save();
    $reloaded_entity = $this->reloadEntity($node);
    $this->assertSame('debug', $reloaded_entity);
  }
}

The debug assert statement shows that the reloaded entity does not contain my custom fields.

If I put a $node->set('field_my_custom_field_1', 'some value') statement in the code instead of passing those fields in the Node::create logic I get an error that the field name is not valid.

8

For kernel tests you need to specify which configurations you want installed. For instance, you'll need something like this in your test's setUp() method:

$this->installConfig(['my_custom_module']);

That takes an array of modules, so you'll probably need to specify additional modules (like filter, node, and field potentially).

This assumes your field configurations are bundled in your module's config/install directory.

| improve this answer | |
  • Thanks for the suggestion. I have used $this->installConfig(['my_custom_module']) as you are suggesting and I still have the same problems. Since I'm using the EntityKernelTestBase some of the other stuff you mention is taken care of in there. I'm going to update my question with more details about what I've got already. – vegantriathlete Mar 3 '17 at 21:17
  • To follow up on your other point, I have defined the custom content type via the config/optional directory. (Recall that the full Functional test works just fine. So, the issue is definitely that I'm missing some things I need to explicitly tell the Kernel test to do.) – vegantriathlete Mar 3 '17 at 21:25
  • Just to test things out, I have included $this->installConfig(['node', 'my_custom_module']); and the $reloaded_entity still does not contain my custom fields. – vegantriathlete Mar 3 '17 at 21:33
  • 1
    Anything in config/optional will only be installed if all dependencies are met, so you could look at your content type, and see which modules it requires, then make sure to enable those as well. For testing purposes, try moving it to config/install, and then when the test is run, any missing dependencies should be printed out in an exception. – jhedstrom Mar 3 '17 at 21:42
  • 1
    Here's the heart of what I needed to do to get it to work. I did need to enable more modules public static $modules = []; and I did need to install some configuration $this->installConfig([]);. In my case I needed to $this->installConfig(['node', 'my_custom_module']);. Yes, it DOES matter if node's configuration is installed first because my_custom_module defines a new content type. It did not matter whether I used config/install or config/optional and I chose to keep things in config/optional. – vegantriathlete Mar 5 '17 at 3:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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