我以前在測試我的自定義服務提供者時遇到類似的問題。我創建了測試特徵來模擬我的服務提供者。
正如您所看到的,我正在爲我的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();
}
}
}