0

我仍在学习 Laravel 和依赖注入。我理解这个概念,但我不知道如何在这种特定情况下模拟依赖项:

MyController.php

use Illuminate\Routing\Controller;    
use MyPackage\Services\ServiceInterface;

class MyController extends Controller{
    protected $service;

    public function __construct(ServiceInterface $service)
    {
        $this->service = $service;
    }    
}

MyServiceProvider.php

use Illuminate\Support\ServiceProvider;

class MyServiceProvider extends ServiceProvider{

    public function register()
    {
        $this->app->bind('MyPackage\Services\ServiceInterface', function ($app) {
            return new MyPackage\Services\ConcreteService(['key'=>'123'], $app->make('GuzzleHttp\Client'));
        });
    }    
}

因此,如您所见,我有一个需要 ServiceInterface 实例的控制器。该实例正在 ServiceProvider 中解析。ConcreteService 的构造函数需要客户端向 API 执行 Http 请求。这个 Http 正在由 Service 容器解析(它将是 Guzzle 的一个实例)。

现在,我如何在我的测试中模拟这个 Guzzle 实例?

理想的结果是做这样的事情:

我的测试.php

...
$this->post(route('routeToActionInMyController'), $params);

因此,在我的测试中,我只需要点击将使用 MyController.php 的特定方法的路线,但我不需要“真正的”Guzzle 实例。我只需要模拟响应以测试 MyController 是否以预期方式运行(并将内容正确存储在数据库中)。

如何指示服务容器仅在测试期间注入模拟对象?还是我以完全错误的方式这样做?

任何帮助将不胜感激。

提前致谢

4

1 回答 1

3

在您的测试课程中:

class TestingSomething extends TestCase {
     protected function setUp() {
          parent::setUp();
          $mockServiceInterface = $this->getMockBuilder(ServiceInterface::class)->getMock();
          $this->app->instance(ServiceInterface::class,$mockServiceInterface);
     }

     public function testPostToRoute() {
        $this->post(route('routeToActionInMyController'), $params);
    }
 } 

这应该用该模拟实例替换服务容器中已经绑定的内容。

请参阅第 9 章的 PHPUnit 手册。测试替身以了解您可以使用模拟构建器和生成的模拟做什么。

于 2017-10-09T13:59:42.510 回答