我还在学习Laravel和Dependency Injection。我理解这个概念,但我不知道在这个特定情况下如何模拟依赖:
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实例?
理想的结果就是做这样的事情:
MyTest.php
...
$this->post(route('routeToActionInMyController'), $params);
所以,在我的测试中,我只需要使用MyController.php的特定方法,但我不需要一个“真正的”Guzzle实例。我只需要模拟响应以测试MyController是否以预期的方式运行(并将数据存储在数据库中)。
如何指示Service Container仅在测试期间注入Mocked对象?或者我是以完全错误的方式做到这一点?
任何帮助将不胜感激。
提前致谢
答案 0 :(得分:1)
在您的测试课程中:
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);
}
}
这应该用该模拟实例替换服务容器中已绑定的内容。
请参阅PHPUnit manual on chapter 9. Test doubles了解如何使用模拟构建器和生成的模拟。