【问题标题】:Mock a service provider - Laravel 5.4模拟服务提供者 - Laravel 5.4
【发布时间】:2017-06-08 08:46:27
【问题描述】:

我在特定控制器中使用服务提供者,我注册了提供者并成功解决了它。

但是我过去通过模拟实际类来运行的测试不再起作用了。

我使用 app() 在我的控制器中解析服务:

$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

有什么想法吗?

【问题讨论】:

    标签: php unit-testing testing laravel-5 mocking


    【解决方案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('client@email.tld');
    
            $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();
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-07-16
      • 1970-01-01
      • 2017-06-13
      • 2016-12-21
      • 2015-10-24
      • 2016-10-06
      • 1970-01-01
      • 1970-01-01
      • 2017-01-11
      相关资源
      最近更新 更多