3

I want to write a Unit test. But the class I want to test has a AccountInterface dependencie Injection.

When I try to get the AccountInterface Object I get:

Drupal\Core\DependencyInjection\ContainerNotInitializedException: \Drupal::$container is not initialized yet. \Drupal::setContainer() must be called with a real container.

My test looks like this

<?php
namespace Drupal\mymodule\test;

use Drupal\mymodule\MyModuleQuery;
use Drupal\Tests\UnitTestCase;
use Drupal\user\Entity\User;

class MyModuleQueryTest extends UnitTestCase {

  protected $user;

  public function __construct() {
    $this->user = \Drupal::currentUser();
  }

  public function testResult() {
    $MyModuleQuery = new MyModuleQuery(1, $this->user);
    $countUser = $MyModuleQuery->mymodule_get_user();
    $countNode = $MyModuleQuery->mymodule_get_node();        
    $bool = FALSE;
    if (!isset($countNode) && !isset($countUser)) {
      $bool = TRUE;
    }
    $this->assertTrue($bool);
  }
}

1 Answer 1

1

You most likely want to mock your dependencies rather than trying to instantiate actual objects because a unit test should only test the class it describes. However this is not always as convenient.

In this case you are trying to call the \Drupal::currentUser static method which is dependent on the dependency injection container. An empty container can be created and used for the test, and test doubles available for it.

protected function setUp() {
  // use Drupal\Core\DependencyInjection\ContainerBuilder;
  $container = new ContainerBuilder();
  $account = $this->prophesize('Drupal\Core\Session\AccountProxyInterface');
  $container->set('current_user', $account->reveal());
  \Drupal::setContainer($container);
  $this->user = \Drupal::currentUser();
}

However you do not actually need the container, and can just use the test double.

public function testResult() {
  $accountProphecy = $this->prophesize('\Drupal\Core\Session\AccountProxyInterface');
  // Mock some methods.
  // $accountProphecy->getUserName()->willReturn('admin');
  $MyModuleQuery = new MyModuleQuery(1, $accountProphecy->reveal());
}
3
  • Unfortunately the last method you mentioned throws me the same error. But the first one works just fine! Is there a similiar way to get the Drupal::database(); ?
    – DiDebru
    Commented Aug 31, 2016 at 6:49
  • 1
    I debated adding a note about needed to set the container anyway because I assumed you were doing a query, but I didn't want to make assumptions in the answer. If your actual class is calling any services you will need to set the container as in the first example, but you only need to set the container with the database service. This is a bit tricky to mock out correctly, but there are some examples in core. OrderByTest has an example using standard PHPUnit Mock Objects.
    – mradcliffe
    Commented Aug 31, 2016 at 11:56
  • And ConditionTest has an example using prophecy.
    – mradcliffe
    Commented Aug 31, 2016 at 11:57

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.