簡體   English   中英

PHP依賴注入與構造函數參數使測試變得困難

[英]PHP dependency injection with constructor arguments making testing difficult

我正在嘗試處理一些依賴注入最佳實踐。 我正在嘗試測試使用braintree/braintree_php庫的服務類。 假設我有一個像這樣的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();

如果我在整個代碼中的多個地方使用此服務,我覺得這會很麻煩。 我會喜歡一些關於如何更好地處理依賴關系的建議,同時仍然能夠完全測試我的服務類。 謝謝!

在構造函數中接受null作為默認值:

public function __construct(Braintree_Gateway $gateway=null) { 
  if(!gateway) { 
    $gateway = new \Braintree_Gateway([
    'environment' => BRAINTREE_ENVIRONMENT,
    'merchantId' => BRAINTREE_MERCHANT_ID,
    'publicKey' => BRAINTREE_PUBLIC_KEY,
    'privateKey' => BRAINTREE_PRIVATE_KEY,
    ]);
  }
}

通過這種方式,您可以覆蓋它以進行測試,但在生產中將其向后兼容

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM