14/01/2017 - BEHAT, SYMFONY
Bu örneğimizde Behat ile test
ortamında Guzzle client taklidini kullanacağız. Bunun nedeni ise, harici API'leri kullanmak istemememizdir.
Uygulamamızı kullandığımız zaman, dev
ve prod
ortamlarında AppBundle\Util\ClientHelper
class kullanılır ama test
ortamında ise AppBundle\Features\Mock\ClientHelperMock
class kullanılır.
parameters:
client_helper_class: AppBundle\Util\ClientHelper
parameters:
client_helper_class: AppBundle\Features\Mock\ClientHelperMock
namespace AppBundle\Service;
use AppBundle\Util\ClientHelper;
use Symfony\Component\HttpFoundation\Request;
class PostcodeService
{
private $client;
private $apiUri;
public function __construct(
ClientHelper $client,
$apiUri
) {
$this->client = $client;
$this->apiUri = $apiUri;
}
public function get($postcode)
{
return $this->client->request(Request::METHOD_GET, $this->apiUri.$postcode);
}
}
service:
app.service.postcode:
class: AppBundle\Service\PostcodeService
arguments:
- "@app.util.client_helper"
- "%postcodes_api%"
namespace AppBundle\Util;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Psr7\Response;
use GuzzleHttp\Psr7\Stream;
class ClientHelper
{
private $client;
public function __construct(ClientInterface $client)
{
$this->client = $client;
}
public function request($method, $uri, array $options = [])
{
$details = null;
try {
/** @var Response $response */
$response = $this->client->request($method, $uri, $options);
/** @var Stream $body */
$body = $response->getBody();
$details = $body->getContents();
} catch (ClientException $e) {
}
return $details;
}
}
services:
app.util.client_helper:
class: '%client_helper_class%'
arguments:
- '@app.util.guzzle'
app.util.guzzle:
class: GuzzleHttp\Client
namespace AppBundle\Features\Mock;
use AppBundle\Util\ClientHelper;
class ClientHelperMock extends ClientHelper
{
public static $data;
public function request($method, $uri, array $options = [])
{
$response = [];
$position = strrpos($uri, '/');
if ($position !== false) {
$postcode = substr($uri, $position+1);
if (isset(self::$data['postcode']) && self::$data['postcode'] == $postcode) {
$response = self::$data['result'];
}
}
return json_encode($response);
}
}
/**
* @param PyStringNode $stringNode
*
* @Given /^the Postcode API is available with data:$/
*/
public function thePostcodeApiIsAvailableWith(PyStringNode $stringNode)
{
ClientHelperMock::$data = json_decode($stringNode->getRaw(), true);
}
Feature: Getting postcode details.
In order to get postcode details
As a user
I should be able call call external API
Scenario: I get empty result for non-existent postcode.
Given the Postcode API is available with data:
"""
{"postcode":"POSTCODE 1","result":{"longitude":-0.11111111,"latitude":0.11111111}}
"""
When I send a "GET" request to "/postcodes/NON-EXISTENT POSTCODE"
Then the response status code should be 200
And the response should contain json:
"""
[]
"""
Scenario: I get full result for existent postcode.
Given the Postcode API is available with data:
"""
{"postcode":"POSTCODE 1","result":{"longitude":-0.11111111,"latitude":0.11111111}}
"""
When I send a "GET" request to "/postcodes/POSTCODE 1"
Then the response status code should be 200
And the response should contain json:
"""
{"longitude":-0.11111111,"latitude":0.11111111}
"""
$ vendor/bin/behat --suite=app src/AppBundle/Features/Postcode.feature
Feature: Getting postcode details.
In order to get postcode details
As a user
I should be able call call external API
Scenario: I get empty result for non-existent postcode.
Given the Postcode API is available with data:
"""
{"postcode":"POSTCODE 1","result":{"longitude":-0.11111111,"latitude":0.11111111}}
"""
When I send a "GET" request to "/postcodes/NON-EXISTENT POSTCODE"
Then the response status code should be 200
And the response should contain json:
"""
[]
"""
Scenario: I get full result for existent postcode.
Given the Postcode API is available with data:
"""
{"postcode":"POSTCODE 1","result":{"longitude":-0.11111111,"latitude":0.11111111}}
"""
When I send a "GET" request to "/postcodes/POSTCODE 1"
Then the response status code should be 200
And the response should contain json:
"""
{"longitude":-0.11111111,"latitude":0.11111111}
"""
2 scenarios (2 passed)
8 steps (8 passed)
0m1.24s (30.72Mb)