How to use transformers?¶
Behat provides many awesome features, and one of them is definitely transformers. They can be used to transform (usually widely used) parts of steps and return some values from them, to prevent unnecessary duplication in many steps’ definitions.
Basic transformer¶
Example is always the best way to clarify, so let’s look at this:
/**
* @Transform /^airport "([^"]+)"$/
* @Transform :airport
* @Transform :airportFrom
* @Transform :airportTo
*
* @param string $data
*
* @return AirportInterface
*/
public function getAirportLike($data)
{
$airport = $this->airportRepository->findOneAirportLike($data);
Assert::notNull($airport, sprintf('Airport "%s" not found.', $data));
return $airport;
}
This transformer is used to return Airport object from proper repository using city name. It also throws exception if such a method does not exist. It can be used in plenty of steps, that have airport name in it.
Note
In the example above a Webmozart assertion library was used, to assert a value and throw an exception if needed.
But how to use it? It is as simple as that:
/**
* @Given /^the airline has an (airport "[^"]+")$/
*
* @param AirportInterface $airport
*/
public function airlineHasAirport(AirportInterface $airport)
{
// some logic here
}
If part of step matches transformer definition, it should be surrounded by parenthesis to be handled as whole expression. That’s it! As it is shown in the example, many transformers can be used in the same step definition. Is it all? No! The following example will also work like charm:
/**
* @When I try to edit airport :airport
*
* @param AirportInterface $airport
*/
public function iTryToEditAirport(AirportInterface $airport)
{
// some logic here
}
It is worth to mention, that in such a case, transformer would be matched depending on a name after ‘:’ sign. So many transformers could be used when using this signature also. This style gives an opportunity to write simple steps with transformers, without any regex, which would boost context readability.
Note
Transformer definition does not have to be implemented in the same context, where it is used. It allows to share them between many different contexts.
Transformers implemented in Openjet¶
Specified¶
There are plenty of transformers already implemented in Openjet and in Sylius. Most of them return specific resources from their repository, for example: role "Admin root" -> find role in their repository with name “Admin root”
You’re free to use them in your own behat scenarios.
Note
All transformers definitions are currently kept in Openjet\Behat\Context\Transform namespace.
Warning
Remember to include contexts with transformers in custom suite to be able to use them!