How to write PHPUnit Test for a module in Magento 2?

All the Core module in Magento natively comes with Unit and Integration Test.

As a professional Developer, When you create any module for your project, You should have to write Unit Test for your module code to validate your code is errorless.

Write a Unit test for your module, Gives guarantee your code is bug-free with Find problems earlier before going live and if any error available for a code, you can update the code before code is going to a production server.

I will give you a simple demo,

How to write a Unit Test for Magento Custom module?

Let’s simple Unit code started with Helper file,
Your Helper file resides under,
app/code/Rbj/UnitTestDemo/Helper/Data.php file,

<?php
/**
 * @author Rakesh Jesadiya
 */

namespace Rbj\UnitTestDemo\Helper;

/**
 * Data Helper
 */
class Data extends \Magento\Framework\App\Helper\AbstractHelper
{
    /**
     * Simple Message
     * @return string
     */
    public function getMessage()
    {
        return 'First Unit Test Demo';
    }
}

As you can see Helper class is pretty straight forward, it just returns a simple string message.

When you need to write a Unit test for any file, you have to create a file structure in the Test/Unit folder.

Filename suffix with Test. Our module Helper file equals DataTest.php

We have to run a unit test in a Helper class,
app/code/Rbj/UnitTestDemo/Test/Unit/Helper/DataTest.php

When you write any test for specific function you can add test name before the function name. Our test function name will be testGetMessage().

<?php
/**
 * @author Rakesh Jesadiya
 */
declare(strict_types=1);

namespace Rbj\UnitTestDemo\Test\Unit\Helper;

/**
 * Test class for Data Helper
 */
class DataTest extends \PHPUnit\Framework\TestCase
{
    /**
     * @var string
     */
    protected $expectedMessage;

    /**
     * Set up
     *
     * @return void
     */
    protected function setUp(): void
    {
        $objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
        $className = \Rbj\UnitTestDemo\Helper\Data::class;
        $arguments = $objectManagerHelper->getConstructArguments($className);
        /*$this->context = $arguments['context'];*/

        $this->helper = $objectManagerHelper->getObject($className, $arguments);
    }

    /**
     * Test for getMessage method
     * @return void
     */
    public function testGetMessage(): void
    {
        $this->expectedMessage = 'First Unit Test Demo';

        $this->assertEquals($this->expectedMessage, $this->helper->getMessage());
        // Optionally
        $this->assertTrue(!empty($this->expectedMessage));
        // Optionally
        $this->assertTrue(strlen($this->expectedMessage)>0);
    }
}

Every Test file must extend \PHPUnit\Framework\TestCase.

You can check above Test file with two methods.
1. setUp() method PHPUnit will automatically call it before each test run.
you can create the objects against which you will test, setUp() run before all the testing methods inside of a test class. You can call the __construct() methods class inside setUp() method.

2. testGetMessage() function we have to test this function from our original Helper file.

Defination:
assertEquals(mixed $expected, mixed $actual[, string $message = ”])
Reports an error identified if the two variables $expected and $actual are not equal.

assertTrue(bool $condition[, string $message = ”])
Reports an error if $condition is false

We will run the Unit test for check the message is correct or not in our file.

$this->assertEquals($this->expectedMessage, $this->helper->getMessage());
$this->expectedMessage is static message.
$this->helper->getMessage() call the actual function and get the actual messsage vaule.

Now We can run the test unit below way,
php vendor/bin/phpunit -c dev/tests/unit/phpunit.xml.dist app/code/Rbj/UnitTestDemo/Test/Unit/Helper/DataTest.php

Output:
Result Successfull indicate .(DOT) (1 test, 3 assertion)

phpunit test magento 2
phpunit test magento 2

Check the Result of a Unit test, How to check the status of each test in PHPUnit Test using CLI?