{"id":57998,"date":"2023-08-29T11:14:19","date_gmt":"2023-08-29T05:44:19","guid":{"rendered":"https:\/\/www.tothenew.com\/blog\/?p=57998"},"modified":"2023-09-06T11:30:04","modified_gmt":"2023-09-06T06:00:04","slug":"concepts-of-unit-testing-in-drupal-9-with-example","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/concepts-of-unit-testing-in-drupal-9-with-example\/","title":{"rendered":"Concepts of Unit Testing in Drupal 9 with Example"},"content":{"rendered":"<h2><b>Introduction<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">In the realm of Drupal 9 development, ensuring the dependability and stability of your applications stands as a paramount objective. The practice of unit testing emerges as a potent strategy to achieve this goal, allowing developers to validate individual building blocks of their codebase. This comprehensive guide takes a deep dive into the intricacies of unit testing within the Drupal 9 context, providing practical examples that underscore its importance.<\/span><\/p>\n<h2><b>Grasping the essence of unit testing and its implications<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">In the dynamic world of software development, unit testing plays a pivotal role by breaking down code into manageable units for targeted evaluation. These discrete tests hold the power to unearth latent bugs, thereby promoting software reliability and performance. In the context of Drupal 9, these units can be functions, methods, or services, forming the bedrock of quality assurance.<\/span><\/p>\n<h2><b>Configuring your local Drupal 9 environment for seamless unit testing<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">Before embarking on your unit testing journey, a local development environment equipped with PHPUnit and the &#8220;Drupal Test Traits&#8221; Composer package is indispensable. This toolkit, comprising traits and utilities tailored to Drupal testing, lays the foundation for effective unit testing. Ensure a smooth installation and alignment of PHPUnit with the package.<\/span><\/p>\n<h2><b>Crafting your maiden Drupal 9 unit test<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">Let&#8217;s illustrate the concept with a scenario: Imagine a custom module containing a function that calculates the sum of two numbers. A simple yet illustrative unit test might look like this:<\/span><\/p>\n<pre><span style=\"font-weight: 400;\">namespace Drupal\\Tests\\test_module\\Unit;<\/span>\r\n<span style=\"font-weight: 400;\">use Drupal\\Tests\\UnitTestCase; <\/span>\r\n<span style=\"font-weight: 400;\">use Drupal\\test_module\\Calculator;\u00a0<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\/** <\/span>\r\n<span style=\"font-weight: 400;\">* Testing the Calculator class. <\/span>\r\n<span style=\"font-weight: 400;\">*<\/span>\r\n<span style=\"font-weight: 400;\">* @group test_module\u00a0<\/span>\r\n\r\n<span style=\"font-weight: 400;\">*\/ <\/span>\r\n<span style=\"font-weight: 400;\">class CalculatorTest extends UnitTestCase{ <\/span>\r\n<span style=\"font-weight: 400;\">public function testSum() { <\/span>\r\n<span style=\"font-weight: 400;\">$calculator = new Calculator(); <\/span>\r\n<span style=\"font-weight: 400;\">$this-&gt;assertEquals(5, $calculator-&gt;sum(2, 3)); <\/span>\r\n<span style=\"font-weight: 400;\">} <\/span>\r\n<span style=\"font-weight: 400;\">}<\/span><\/pre>\n<h2><b>Probing Deeper: Unveiling the secrets of testing Drupal services<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">The architecture of Drupal relies extensively on services. Delving into service testing, we leverage the &#8220;Container&#8221; trait, a gem from the &#8220;Drupal Test Traits&#8221; package. This example illustrates creating a service instance:<\/span><\/p>\n<pre><span style=\"font-weight: 400;\">namespace Drupal\\Tests\\test_module\\Unit;\u00a0<\/span>\r\n\r\n<span style=\"font-weight: 400;\">use Drupal\\Tests\\UnitTestCase; <\/span>\r\n<span style=\"font-weight: 400;\">use Drupal\\test_module\\MyService; <\/span>\r\n<span style=\"font-weight: 400;\">use Drupal\\Core\\DependencyInjection\\ContainerBuilder; <\/span>\r\n<span style=\"font-weight: 400;\">use Drupal\\Core\\DependencyInjection\\Container;\u00a0<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\/** <\/span>\r\n<span style=\"font-weight: 400;\">* Testing the MyService class. <\/span>\r\n<span style=\"font-weight: 400;\">* <\/span>\r\n<span style=\"font-weight: 400;\">* @group test_module *\/\u00a0<\/span>\r\n\r\n<span style=\"font-weight: 400;\">class MyServiceTest extends UnitTestCase { <\/span>\r\n<span style=\"font-weight: 400;\">protected function setUp(): void { <\/span>\r\n<span style=\"font-weight: 400;\">parent::setUp(); <\/span>\r\n<span style=\"font-weight: 400;\">$this-&gt;container = new Container(new ContainerBuilder()); <\/span>\r\n<span style=\"font-weight: 400;\">}\u00a0<\/span>\r\n\r\n<span style=\"font-weight: 400;\">public function testSomething() { <\/span>\r\n<span style=\"font-weight: 400;\"> $my_service = new MyService($this-&gt;container);\u00a0<\/span>\r\n<span style=\"font-weight: 400;\"> $result = $my_service-&gt;doSomething();\u00a0<\/span>\r\n<span style=\"font-weight: 400;\"> $this-&gt;assertEquals('expected_result', $result);\u00a0<\/span>\r\n<span style=\"font-weight: 400;\"> } <\/span>\r\n<span style=\"font-weight: 400;\">}<\/span><\/pre>\n<pre><span style=\"font-weight: 400;\">namespace Drupal\\Tests\\test_module\\Unit; <\/span>\r\n\r\n<span style=\"font-weight: 400;\">use Drupal\\Tests\\UnitTestCase; <\/span>\r\n<span style=\"font-weight: 400;\">use Drupal\\test_module\\MyService; <\/span>\r\n<span style=\"font-weight: 400;\">use Prophecy\\Prophet;\u00a0<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\/** <\/span>\r\n<span style=\"font-weight: 400;\"> * Testing the MyService class.\u00a0<\/span>\r\n<span style=\"font-weight: 400;\"> *\u00a0<\/span>\r\n<span style=\"font-weight: 400;\"> * @group test_module *\/\u00a0<\/span>\r\n<span style=\"font-weight: 400;\">class MyServiceTest extends UnitTestCase { \r\n<\/span>\r\n<span style=\"font-weight: 400;\">public function testSomething() { <\/span>\r\n<span style=\"font-weight: 400;\"> \u00a0\u00a0$prophet = new Prophet();\u00a0<\/span>\r\n<span style=\"font-weight: 400;\"> \u00a0\u00a0$dependency = $prophet-&gt;prophesize(AnotherService::class);<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0$dependency-&gt;someMethod()-&gt;willReturn('mocked_result');<\/span>\r\n\r\n<span style=\"font-weight: 400;\"> \u00a0\u00a0$my_service = new MyService($dependency-&gt;reveal());\u00a0<\/span>\r\n<span style=\"font-weight: 400;\"> \u00a0\u00a0$result = $my_service-&gt;doSomething();\u00a0<\/span>\r\n<span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0$this-&gt;assertEquals('expected_result', $result);\u00a0<\/span>\r\n\r\n<span style=\"font-weight: 400;\"> \u00a0\u00a0$prophet-&gt;checkPredictions();\u00a0<\/span>\r\n<span style=\"font-weight: 400;\"> }\u00a0<\/span>\r\n<span style=\"font-weight: 400;\">}<\/span><\/pre>\n<h2><b>Embracing diverse scenarios with data providers<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">Enhancing testing coverage is achievable through data providers. This technique enables tests to run with various inputs, effectively broadening their scope:<\/span><\/p>\n<pre><span style=\"font-weight: 400;\">namespace Drupal\\Tests\\test_module\\Unit;<\/span>\r\n<span style=\"font-weight: 400;\">use Drupal\\Tests\\UnitTestCase;<\/span>\r\n<span style=\"font-weight: 400;\">use Drupal\\test_module\\Calculator;<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\/**<\/span>\r\n<span style=\"font-weight: 400;\">* Testing the Calculator class.<\/span>\r\n<span style=\"font-weight: 400;\">*<\/span>\r\n<span style=\"font-weight: 400;\">* @grouptest_module<\/span>\r\n<span style=\"font-weight: 400;\">*\/ class CalculatorTest extends UnitTestCase{<\/span>\r\n\r\n<span style=\"font-weight: 400;\">\/**<\/span>\r\n<span style=\"font-weight: 400;\">* @dataProvider sumDataProvider<\/span>\r\n<span style=\"font-weight: 400;\">*\/ public function testSum($a, $b, $expected) { $calculator = new Calculator();<\/span>\r\n<span style=\"font-weight: 400;\"> $this-&gt;assertEquals($expected, $calculator-&gt;sum($a, $b));<\/span>\r\n<span style=\"font-weight: 400;\"> }<\/span>\r\n<span style=\"font-weight: 400;\">public function sumDataProvider() { return [ [2, 3, 5], [0, 0, 0], [-1, 1, 0], ];<\/span>\r\n<span style=\"font-weight: 400;\">}<\/span>\r\n<span style=\"font-weight: 400;\">}<\/span><\/pre>\n<h2><b>Navigating the execution and Analysis of unit tests<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">Execute your tests with the command<\/span><\/p>\n<pre><span style=\"font-weight: 400;\">phpunit -c web\/core web\/modules\/custom\/test_module\/tests\/src\/Unit,<\/span><\/pre>\n<p><span style=\"font-weight: 400;\">Where web\/core denotes the Drupal core directory, PHPUnit streamlines the identification of passed and failed tests, expediting issue resolution.<\/span><\/p>\n<h2><b>In Conclusion<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">Elevating code integrity through thoughtful unit testing<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The realm of unit testing in Drupal 9 empowers developers to build robust applications of enduring quality. By scrutinizing discrete code units meticulously, latent defects are unearthed, paving the way for preemptive remediation. With the synergistic interplay of PHPUnit and the &#8220;Drupal Test Traits&#8221; package, the embrace of unit testing within the Drupal ecosystem emerges as a transformative endeavor.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">If you have any questions, please feel free to reach out via comments.<\/span><\/p>\n<p>&nbsp;<\/p>\n<div class=\"ap-custom-wrapper\"><\/div><!--ap-custom-wrapper-->","protected":false},"excerpt":{"rendered":"<p>Introduction In the realm of Drupal 9 development, ensuring the dependability and stability of your applications stands as a paramount objective. The practice of unit testing emerges as a potent strategy to achieve this goal, allowing developers to validate individual building blocks of their codebase. This comprehensive guide takes a deep dive into the intricacies [&hellip;]<\/p>\n","protected":false},"author":1513,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":43},"categories":[3602,1816],"tags":[5152,5398,5400,5399],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/57998"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/1513"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=57998"}],"version-history":[{"count":5,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/57998\/revisions"}],"predecessor-version":[{"id":58332,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/57998\/revisions\/58332"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=57998"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=57998"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=57998"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}