SuperAPI AI Directory

drupal-unit

Testing & quality

View repository

Updated 10-15 21:37

About this skill

Drupal Unit Tests

When to Use

  • Pure PHP logic with no Drupal dependencies
  • Utility functions, data transformations, value objects
  • Classes where all dependencies can be mocked

Basic Structure

// tests/src/Unit/MyServiceTest.php
namespace Drupal\Tests\my_module\Unit;

use Drupal\Tests\UnitTestCase;
use Drupal\my_module\Service\MyService;
use Psr\Log\LoggerInterface;

/**

  • @coversDefaultClass \Drupal\my_module\Service\MyService
  • @group my_module */ final class MyServiceTest extends UnitTestCase {

private MyService $service;

protected function setUp(): void { parent::setUp();

$logger = $this->createMock(LoggerInterface::class);
$this->service = new MyService($logger);

}

/**

  • @covers ::processData */ public function testProcessData(): void { $input = ['foo' => 'bar']; $result = $this->service->processData($input);
$this->assertArrayHasKey('processed', $result);
$this->assertTrue($result['processed']);

}

/**

  • @covers ::processData */ public function testProcessDataWithEmptyInput(): void { $this->expectException(\InvalidArgumentException::class); $this->service->processData([]); }

}


## Mocking with PHPUnit

```php
// Mock a simple interface
$mock = $this->createMock(SomeInterface::class);
$mock->method('someMethod')->willReturn('value');

// Mock with argument matching
$mock->expects($this->once())
  ->method('someMethod')
  ->with($this->equalTo('expected-arg'))
  ->willReturn('result');

// Mock throwing exception
$mock->method('someMethod')->willThrowException(new \RuntimeException('Error'));

// Stub multiple calls
$mock->method('someMethod')
  ->willReturnMap([
    ['arg1', 'result1'],
    ['arg2', 'result2'],
  ]);

Mocking Drupal Translation (t())

// UnitTestCase provides getStringTranslationStub()
$this->service = new MyService(
  $this->getStringTranslationStub()
);

Mocking Logger

// Expect a specific log message
$logger = $this->createMock(LoggerInterface::class);
$logger->expects($this->once())
  ->method('error')
  ->with($this->stringContains('Failed to process'));

Running Tests

Examples assume a docroot/-based Drupal project. If your project uses web/ or another document root, adjust paths accordingly.

# Run specific test file
ddev exec vendor/bin/phpunit docroot/modules/custom/my_module/tests/src/Unit/MyServiceTest.php

# Run all unit tests for a module
ddev exec vendor/bin/phpunit docroot/modules/custom/my_module/tests/src/Unit/

# Run with verbose output
ddev exec vendor/bin/phpunit --verbose docroot/modules/custom/my_module/tests/