Я пытаюсь разобраться в некоторых лучших практиках внедрения зависимостей.Я пытаюсь протестировать класс обслуживания, использующий библиотеку braintree/braintree_php
composer.Предположим, у меня есть класс BraintreeService
, подобный этому:
namespace App\Service;
class BraintreeService
{
/* @var Braintree_Gateway */
private $gateway;
public function __construct()
{
$this->gateway = new \Braintree_Gateway([
'environment' => BRAINTREE_ENVIRONMENT,
'merchantId' => BRAINTREE_MERCHANT_ID,
'publicKey' => BRAINTREE_PUBLIC_KEY,
'privateKey' => BRAINTREE_PRIVATE_KEY,
]);
}
/*
* Generate a new client token from Braintree
*
* @return string $string
*/
public function getClientToken() : string
{
return $this->gateway->clientToken()->generate();
}
}
Использование этого класса будет выглядеть следующим образом:
$btService = new \App\Service\BraintreeService();
$token = $btService->getClientToken();
Очевидная проблема заключается в том, что этот класс обслуживания теснозависит от Braintree_Gateway
.Таким образом, сделать юнит-тестирование BraintreeService
затруднительным.Чтобы упростить тестирование, я бы хотел переместить Braintree_Gateway
в аргумент конструктора.Это позволило бы мне смоделировать класс Braintree_Gateway
в моем модульном тесте.
Однако, насколько я понимаю, если я это сделаю, то код будет выглядеть так:
namespace App\Service;
class BraintreeService
{
/* @var Braintree_Gateway */
private $gateway;
public function __construct(Braintree_Gateway $gateway)
{
$this->gateway = $gateway;
}
/*
* Generate a new client token from Braintree
*
* @return string $string
*/
public function getClientToken() : string
{
return $this->gateway->clientToken()->generate();
}
}
Использование этого класса тогда выглядело бы так:
$btService = new \App\Service\BraintreeService(
new \Braintree_Gateway([
'environment' => BRAINTREE_ENVIRONMENT,
'merchantId' => BRAINTREE_MERCHANT_ID,
'publicKey' => BRAINTREE_PUBLIC_KEY,
'privateKey' => BRAINTREE_PRIVATE_KEY,
])
);
$token = $btService->getClientToken();
Мне кажется, что это станет громоздким, если я буду использовать этот сервис в нескольких местах кода.Мне бы хотелось получить несколько советов о том, как лучше справляться с зависимостями, но при этом полностью проверить свой класс обслуживания.Спасибо!