2017-06-08 149 views
0

我在特定的控制器中使用服務提供商,我註冊了提供商併成功解決了它。模擬服務提供商 - Laravel 5.4

但我用來模擬實際類的測試不再工作。

$cart = app()->make('Cart'); 

這是我用來切換到服務提供商之前嘲笑它:

$this->cart = $this->createMock(Cart::class); 

現在,如果我想

我使用的應用程序()解析服務在我的控制器嘲笑它,我正在做這樣的事情:

$this->createMock(app()->make('Cart')); 

並且測試失敗並顯示錯誤:

PHPUnit_Framework_MockObject_Generator::getMock() must be a array or string 

任何想法?

回答

1

我以前在測試我的自定義服務提供者時遇到類似的問題。我創建了測試特徵來模擬我的服務提供者。

正如您所看到的,我正在爲我的Firebase服務提供商重新申報singleton,之後在我的測試用例中使用use FirebaseProvider

// FirebaseServiceProvider 

namespace App\Providers; 

use Kreait\Firebase; 
use Kreait\Firebase\ServiceAccount; 
use Kreait\Firebase\Factory as FirebaseFactory; 
use Illuminate\Support\ServiceProvider; 

class FirebaseServiceProvider extends ServiceProvider 
{ 
    ... 

    public function register() 
    { 
     $this->app->singleton(Firebase::class, function() { 
      return (new FirebaseFactory()) 
       ->withServiceAccount(ServiceAccount::fromJsonFile(env('FIREBASE_SERVICE_ACCOUNT'))) 
       ->create(); 
     }); 

     $this->app->alias(Firebase::class, 'firebase'); 
    } 
} 

// In ./tests/FirebaseProvider.php 

namespace Tests; 

use Kreait\Firebase; 
use GuzzleHttp\Psr7\Uri; 
use Firebase\Auth\Token\Handler; 
use Kreait\Firebase\ServiceAccount; 

trait FirebaseProvider 
{ 

    public function mockFirebaseServiceProvider() 
    { 
     $serviceAccountMock = $this->createMock(ServiceAccount::class); 

     $serviceAccountMock->expects($this->any()) 
      ->method('getProjectId') 
      ->willReturn('project'); 

     $serviceAccountMock->expects($this->any()) 
      ->method('getClientId') 
      ->willReturn('client'); 

     $serviceAccountMock->expects($this->any()) 
      ->method('getClientEmail') 
      ->willReturn('[email protected]'); 

     $serviceAccountMock->expects($this->any()) 
      ->method('getPrivateKey') 
      ->willReturn('some private key'); 

     uopz_flags(Handler::class, null, 0); // hack: removes `final` keyword so we can mock-it 
     $tokenHandlerMock = $this->createMock(Handler::class); 

     $tokenHandlerMock->expects($this->any()) 
      ->method('createCustomToken') 
      ->willReturn(new \Lcobucci\JWT\Token()); 

     $this->app->singleton(Firebase::class, function() { 
      return $this->createMock(Firebase::class); 
     }); 
    } 

} 

abstract class TestCase extends BaseTestCase 
{ 
    .... 

    protected function setUpTraits() 
    { 
     parent::setUpTraits(); 

     $uses = array_flip(class_uses_recursive(static::class)); 

     if (isset($uses[FirebaseProvider::class])) { 
      $this->mockFirebaseServiceProvider(); 
     } 
    } 
}