Testing

Mix Prophecy Mock Framework with PHPUnit Mock Builder to Create Mocks for Not Existing Classes and Magic Methods

Submitted by Peter Majmesku on Wed, 08/16/2017 - 12:20

Prophecy is great as long as you are creating mocks for classes or methods, which are existing in your code base. The benefit is, that the usage is a bit more convenient compared with the PHPUnit mock builder (e.g. method definition and parameter handling). Therefor Prophecy is integrated into PHPUnit by default.

If you want to create mocks for classes, which are not existing in your code base or if you want to mock magic methods, this will become a problem. You could create a real class, just to have the class/method. But this is not an nice solution. That's why mixing mocking functionality from the Prophecy mocking framework and the PHPUnit mocking framework makes sense.

Here I am not questioning, if it is good to create tests for classes, that do not belong to your code base. I am just showing a way to handle this.

The following example works with PHPUnit 4.8.35 and up. The Prophecy mocking framework is part of PHPUnit.

// Mock the object via Prophecy - generally more convenient than with PHPUnit itself
$entityManager $this->prophesize(EntityManager::class);

// Create the mock object by PHPUnit, for a class that does not exist.
$shippingMethodRepository $this->getMockBuilder('ShippingMethod')
    ->
disableOriginalClone()
    ->
setMethods(['findByName'])
    ->
getMock();

// Set the not existing method.
$shippingMethodRepository->method('findByName')
    ->
willReturn(['Spedition''Hermes']);

// Define that getRepository() can retrieve any arguments and get a "real" object to test with.
$entityManager->getRepository(Prophecy\Argument::any())
    ->
willReturn($shippingMethodRepository);

// Mock a few methods with Prophecy as you like
$entityManager->persist(Prophecy\Argument::any())->willReturn(null);
$entityManager->flush(Prophecy\Argument::any())->willReturn(null);

// Get the mocked object, which will fake behavior
$entityManager->reveal();

// Will return 'Hermes'
end($entityManager->getRepository('AppBundle:ShippingMethod')->findByName('Delivery')); 

Drupal 8: Debug Kernel, Functional and Unit Tests in PhpStorm by Xdebug

Submitted by Peter Majmesku on Sun, 04/16/2017 - 20:21

The following article is valid for unix based systems like Ubuntu Linux. It teaches you, how to setup your PhpStorm IDE to debug your unit tests via the Xdebug PHP extension in Drupal 8.

  1. Make sure you have read the article at https://www.drupal.org/docs/8/phpunit/running-phpunit-tests to understand how to run automated tests in Drupal 8.
  2. Make sure you have read the article at https://www.jetbrains.com/help/phpstorm/2017.1/configuring-xdebug.html to understand how to setup the Xdebug PHP extension on your system and configure it within PhpStorm.

phpunit.xml Configuration File

For the PhpStorm config you need to make sure to have the phpunit.xml file created by copying the ~/PhpstormProjects/drupal-8.x/core/phpunit.xml.dist into the same directory. Afterwards you must set the environment variables for 

  • SIMPLETEST_BASE_URL
  • SIMPLETEST_DB
  • BROWSERTEST_OUTPUT_DIRECTORY
    • Example value: ~/PhpstormProjects/drupal-8.4.x-dev/sites/simpletest/browser_output
  • PHP_IDE_CONFIG
    • Example value: serverName=d8-4x.dev
    • Be careful in this line! Here you set a key-value pair in the value field. Do not use any quotes here. The full line entry in my config is: <env name="PHP_IDE_CONFIG" value="serverName=d8-4x.dev"/>
  • XDEBUG_CONFIG
    • Example value: idekey=PHPSTORM
    • Again: a key-value pair as value.

in your newly created phpunit.xml file.

PHPUnit Config in Your PhpStorm Project

Make sure you have configured:

  • path to the autoloader script from composer. It is located in ~/PhpstormProjects/drupal-8.4/vendor/autoload.php
  • path to your phpunit.xml file

The config window must look according to the following screenshot (be careful about the paths on your system):

 

PHPUnit config

Define the Server Setting and Map the Tests Directory

Set exactly the same value, which you have previously set in your phpunit.xml file inside the PHP_IDE_CONFIG environment variable for your server. You must also map the directory where your tests are. Do your settings according to the screenshot below.

Server setting directory mapping.

Path to CLI PHP Interpreter

Set the path to the PHP interpreter which is running your command line based scripts. It is usually located at /usr/bin/php. The config must look like in the following screenshots.

php interpreter
php cli

Run a Test File

For being able to execute your test quickly, open the PHP file with your test and hit the debug icon.

Run the test

Step Into Your PHP Code

Chances are, that PhpStorm will output a error message like

Remote file path '/home/your-user/PhpstormProjects/drupal-8.4.x-dev/-' is not mapped to any file path in project.

You can ignore this error and just click the "resum program" button. PhpStorm will reveal the PHP interpreter on your breakpoint quickly. If you know, how the reason for this message can be solved - please put me a hint in the comments. However you could create a file with the name "-" and map to this file in the path settings, but this is not a real fix.

Path settings
Happy debugging

Run Behat tests on Ubuntu 16.10

Submitted by Peter Majmesku on Wed, 10/19/2016 - 15:35

To make it work you need Selenium standalone in version 2.52 and Firefox in version 45. This combination does work. The others do not. Download Selenium standalone in version 2.52 from 

http://selenium-release.storage.googleapis.com/index.html?path=2.52/

Then modify your

/etc/apt/sources.list

to use the packages from Ubuntu 16.04 Xenial. This is described at http://packages.ubuntu.com/xenial/arm64/firefox/download. Afterwards update your package manager, check for the proper package version and install it:

sudo apt update

sudo apt-cache show firefox | grep Version

sudo apt-get install firefox=45.0.2+build1-0ubuntu1

Afterwards you are able to execute your Behat tests. F.e. by this command:

bin/behat --suite=my-test-suite

Subscribe to Testing