Magento 2 – How to Run PHPUnit for Testing

magento2phpunitunit tests

I tried to run a unit but failed with the following error.

My test class

<?php

namespace Vendor\Module\Test\Unit\Observer;

class CheckoutOnepageControllerSuccessActionObserverTest extends \PHPUnit_Framework_TestCase {

    public function testExecute() {
        $this->assertTrue(false);
    }

}

I run the phpunit command at /dev/tests/unit/

phpunit --filter CheckoutOnepageControllerSuccessActionObserverTest

It returns the following errors

PHP Fatal error:  Call to protected method PHPUnit_Framework_TestCase::getMockForAbstractClass() from context 'Magento\Framework\TestFramework\Unit\Helper\ObjectManager' in /vendor/magento/framework/TestFramework/Unit/Helper/ObjectManager.php on line 139

Fatal error: Call to protected method PHPUnit_Framework_TestCase::getMockForAbstractClass() from context 'Magento\Framework\TestFramework\Unit\Helper\ObjectManager' in /vendor/magento/framework/TestFramework/Unit/Helper/ObjectManager.php on line 139

Best Answer

The error probably is caused by some other test initializing an object with the object manager during construction, which is trying to mock the arguments.
This shouldn't happen unless the tests actually are being executed. Given the code and the command you posted, the error is not on your side.

Workaround

If you only want to run a single test class, it is much faster to specify the file as a command line argument instead of using the --filter parameter.

When using --filter phpunit will scan all tests for matches. This takes a long time, and along the way the error you encountered is triggered.

Instead, execute phpunit as follows.

From dev/tests/unit:

../../../vendor/bin/phpunit ../../../app/code/Vendor/Module/Test/Unit/Observer/CheckoutOnepageControllerSuccessActionObserverTest.php

Or from the Magento base directory:

vendor/bin/phpunit -c dev/tests/unit/phpunit.xml.dist app/code/Vendor/Module/Test/Unit/Observer/CheckoutOnepageControllerSuccessActionObserverTest.php

The phpunit command can also take a directory path instead of a file, which will limit the scanning for tests to that directory branch.
You can still use --filter to limit the test run to a single test method if you need to.