模拟服务提供商 - Laravel 5.4

时间:2017-06-08 08:46:28

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

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

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

我使用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

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

我在测试自定义服务提供程序时遇到过类似的问题。我创建了测试特性来模拟我的服务提供商。

正如您所看到的,我正在为我的Firebase服务提供商重新声明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();
        }
    }
}
ptr